来 DTDS 全球数字人才发展峰会,与刘润、叶军、快刀青衣畅聊成长>> 了解详情
写点什么

于我而言,Go 语言是新的 Ruby

2019 年 11 月 12 日

于我而言,Go语言是新的Ruby

在决定重写 dnscrypt-proxy 这个项目之后,作者发现即使最初用的是 C 语言,有一些很好的库,但用其开发异步网络功能仍然需要写大量的代码,对应的开发者社区也正在消亡。因此,作者尝试使用 Go 语言进行重写,即便被很多人反对,但作者依旧决定这么做,并发现这是 Ruby 后第二个让作者感受到编程乐趣的语言。



与 Ruby 结缘

我是在Ruby on Rails发布的时候与 Ruby 结缘的。当时,PHP 在 Web 开发领域无处不在,但还没有真正意义上的框架。Rails 的出现改变了游戏规则,约定优于配置(Convention over Configuration)是一个很神奇的东西。按照约定起名字,框架知道如何让应用程序的其他部分来访问这些命名,不需要编写任何多余的代码!使用 Rails 开发网站的体验非常棒,它会帮助处理很多事情。这样,开发人员就可以专注在描述逻辑而不是实现细节上。


比起Rails,我更喜欢 Ruby。对于 Ruby 解释器和编译器开发人员来说,Ruby 的语法有点糟糕。但作为一名普通的开发人员,使用 Ruby 是一种乐趣,这是一种非常灵活的语言,做一件事情可以使用多种不同的方法。但如果被滥用,可能会成为一个弱点(运行时修改会导致 Ruby 变成一种完全不一样的语言),但这也是 Ruby 非常好的特性。


Ruby 不像Rust那样,编译器会不停地出问题,即使你在尽力遵守制定的规则。不管怎样,在使用 Ruby 时,开发人员可以用一种简单而自然的方式表达想要做的事情。人们经常说 Ruby 是为开发人员的幸福感而进行的优化,这绝对是真的,可以使用 Ruby 快速且毫不费劲地完成工作。Ruby 不只是一门利基语言,它的可用模块(gem)数量很惊人,想要为开发应用程序找到合适的工具通常都不是问题。


当然,Ruby 代码的运行速度不会像其他语言那样快。但在效率方面,Ruby 是首屈一指的。一个有实际用处的应用程序比运行速度快但不成熟的应用程序更有价值。


在 OpenDNS(现在是 Cisco)工作期间,我几乎什么事情都用 Ruby 来完成。我是数据处理团队的一员,我们可以自由地使用任何一门编程语言来完成任务,所以我选择了 Ruby。


Hadoop的作业也是用 Ruby 开发的(这要感谢 JRuby)。当然,如果这些东西是用 Java 开的,会运行得更快,但 Ruby 是一种可用于快速试错然后做出改进的语言,在这方面,Ruby 是完美的。


我用 Ruby 在周末开发的一个项目(DNS 数据库)现在成了思科的一款核心产品,而且卖得很火。当时,我只是想基于我们现有的数据做一些实验而已。如果我用了其他效率不那么高的语言,我还会完成这个项目吗?可能不会。因为那样的话一个周末可能不够,而且也不可能在我的业余时间完成这件事。


后来,我用 C 语言和 Rust 重写了部分东西,让运行速度更快一些,但如果没有之前 Ruby 的效率和易用性,这个项目可能永远不会存在。


那个时候,我的大多数开源项目都是用 C 语言或 PHP 开发的(还有其他一些我接触过的语言,比如 Erlang)。但我在笔记本电脑和服务器上运行的所有闭源脚本都是用 Ruby 编写的。我的个人网站也是用 Ruby 开发的。因为我只是想让这些脚本做我需要做的事情,不需要花很多时间在如何编写它们上。


试试 Go 语言

在 Rust 发布第一个公开版的时候,我试了一把,因为尝试新语言总是很有趣。虽然说所有的编程语言都很糟糕,但都带来了一些有趣的概念,这些概念可以让你成为更好的程序员。


从是否对开发人员友好的角度来看,Rust 与 Ruby 是完全相反的。早期的 Rust 与现在的 Rust 有很大的不同。在 OVH 的时候,我还学了Scala,因为需要开发 Spark 应用程序,我不得不用 Scala 来写代码。那个时候 Ruby 用得并不多,但仍然有很多运行在服务器端的东西是用 Ruby 开发的,它们不怎么需要维护。


所以,我使用 Ruby 的机会越来越少,但有越来越多的机会使用 Rust,尽管这门语言最终让我变成了一个脾气暴躁的人,完全不像使用 Ruby 时那样享受写代码的乐趣。


有一天,我想要完全重写 dnscrypt-proxy(https://github.com/DNSCrypt/dnscrypt-proxy)。


我用 C 语言开发了最初的版本,但维护这些代码非常痛苦。即使 C 语言有一些很好的库,但用它开发异步网络功能仍然需要写大量的代码,但获得的效果却很有限,而且还要很费劲地确保所有东西都能可靠、安全地运行。


有些功能已经计划了一段时间(比如匿名 DNS),但没有时间去实现它们。C 语言是一种奇妙的系统语言,但在其他方面并不是最有效率的语言。即使是增加一个很小的功能也会花费我更多的时间。


C 语言的另一个缺点是开发者社区正在消亡。自从 dnscrypt-proxy 这个项目开始以来,用于改进代码或添加新功能的拉取请求(PR)数量为零。即使这个项目有一个相当大的用户群,包括企业用户。


因此,我决定试试 Go 语言。


我没有使用 Go 语言的经验,我只知道它有“goroutine”的概念,这看起来很有趣。另外,它的编译速度也很快。这一决定受到了 dnscrypt-proxy 前用户的严厉批评:Go 太臃肿了!看这些二进制文件有多大!看看内存使用情况!而且可能运行得很慢!


现在回想起来,选择 Go 语言可能是我做过最好的决定。如果是在今天,我一定会再选它,让我来说一下我的理由。


Go语言比 Ruby 更有见地。与那些鼓励使用复杂结构来显摆的语言不同,Go 代码简单易读。Go 语言很稳定,而且向后兼容。因此,为了支持新系统,或者为了提高应用程序的速度,我只需要用新版本重新编译就可以了。


Go 编译器的运行速度非常快。在进行快速迭代时,这个非常有用,因为在修改少量代码后可以立即编译,然后进行测试。用来开发 Go 代码的工具非常好用。VSCode 自动添加导入(但这并不总是一个好主意,稍后会详细介绍),为表达式找到正确的类型,并且提供了自动完成功能(感觉非常棒,特别是对于从 Rust 转过来的人来说)。Go 语言的文档非常出色,提供了很多示例,而不仅仅是内部细节。


尽管我之前没有使用 Go 语言的经验,但我很快就得到了我想要的东西。那时,dnscrypt-proxy 的 C 语言版本已经有 5 年的历史,我在一周内重写了它的部分功能。实现一个基本的代理只需要 15 分钟。


除了 Go 语言和相应的工具,我完成这些东西还要多亏了 Go 语言的可用模块,以及它优秀的标准库。是的,还有 goroutine。


Go 语言是一门非常高效的语言。我喜欢用 Go 语言写代码,因为我可以看到应用程序按照我想要的方式演化,而不需要修改很多代码,也不需要在添加一行代码前花很多时间思考可不可以通过编译。


Go 语言的另一个优势是可移植性。当然,很多语言也是高度可移植的,不过 Go 的库在设计时都考虑到了可移植性,如果有必要的话可以在提供统一接口的情况下模拟所有缺失的东西。


我主要用 MacBook 写代码,但有了 Go 语言之后,我可以非常自信地说,相同的代码可以在任何受支持的平台上以完全相同的方式运行。


Go 语言的交叉编译比我见过的任何编译器都要简单。现在,dnscrypt-proxy 的每个版本都被自动打包成 23 个不同的语言版本,因为这样做非常简单,而且我确信它们在其他平台上运行与在我的开发平台上运行时的行为是完全一样的。


Go 语言有指针,生成的代码到处都有边界检查。与 C 语言不同,如果指针没有被正确使用,程序会自动安全崩溃,并打印出全面的堆栈跟踪信息。


说到堆栈跟踪和调试,Go 语言在这方面绝对是很棒的。Go 语言的堆栈跟踪信息简短、易读,并且包含需要的所有内容,用 VSCode 和 delve 来调试 Go 代码也很棒。


Go 语言的生态系统很大,无论何时需要什么,都能找到需要的模块。Go 语言的社区很强大,每当我被问题困住的时候,总能从社区中找到答案。


我在 Go 语言中找到了最初在 Ruby 中找到的东西。Go 语言是一种让我可以用自然的方式表达想法的语言。我的应用程序迭代得很快,编程再次让我感到兴奋。


“但 Go 语言是有 GC 的!”


是的,那又怎样?就像 Java 一样,如果我需要速度,可以预先分配和重用内存来避免 GC。我可以先用一种简单而自然的方式编写想要的代码,然后花时间对其进行优化,避免后面出现 GC 暂停。


因此,Go 语言的运行速度并不慢,可以 FastHTTP(https://github.com/valyala/fasthttp)为例。


“但它无法防止出现数据竞争!”


Rust 迫使我以一种不自然的方式写代码。我发现自己花了太多时间在思考代码是否可以通过编译,而有些问题在运行时可能并不会发生。有时候,我也会欣赏语言的严格性,它迫使我以某种方式设计代码,避免出现某些问题。但是,我也欣赏与我心智模型匹配且不会给我造成障碍的语言,特别是如果这门语言有很棒的调试工具。


Go 语言的效率让我可以更多地关注算法而不是实现。总的来说,Go 语言大获全胜。根据反馈,dnscrypt-proxy 的第二个版本比 C 语言版本要快得多。更重要的是,它提供了大量功能,如果我没有改用 Go 语言,或许就永远不会实现这些功能。


对我来说,Go 语言已经成了新的 Ruby。我用它来完成工作,并再次享受编程的乐趣。


原文链接:


https://00f.net/2019/10/28/go-is-the-new-ruby/


2019 年 11 月 12 日 08:004264
用户头像
赵钰莹 InfoQ高级编辑

发布了 704 篇内容, 共 414.7 次阅读, 收获喜欢 2285 次。

关注

评论

发布
暂无评论
发现更多内容

你问我答:现有的应用有必要做微服务改造吗?

BoCloud博云

DevOps 微服务 容器云 云平台 博云

华为云FusionInsight大数据技术普惠创新,释放千行百业数据价值

FI洞见

大数据 FusionInsight 华为云

某程序员毕业进UC,被阿里收购!跳去优酷土豆,又被阿里收购!再跳去饿了么,还被阿里收购!难道阿里想收购的是他?

程序员生活志

职场 阿里

人的转型才是关键 数字化时代你具备数字领导力么

CECBC区块链专委会

区块链 数字化时代

云算力挖矿平台APP,算力挖矿建设开发

13530558032

SpreadJS 纯前端表格控件应用案例:MHT-CP数据填报采集平台

Geek_Willie

SpreadJS 纯前端表格控件应用案例:雨诺订单管理系统(雨诺OMS)

Geek_Willie

Spring Bean处理器

TinyKing

Spring Framework

关于显性知识和隐性知识

Tanmer

知识管理 知识产权

十年Java开发传奇经历:我是如何从外包逆袭成为大厂架构师的

Java成神之路

Java 程序员 面试 微服务 多线程

腾讯技术专家图解29种设计模式中常见问题类级与方法级解决方案

周老师

Java 编程 程序员 架构 面试

当有人把GoF的23个设计模式嚼碎给你——你才会发现有多简单

周老师

Java 编程 程序员 架构 面试

XSKY对象存储获全球备份领域领导者Commvault官方认证

XSKY融合存储

区块链支付新模式开发,USDT支付系统搭建

13530558032

大数据应用场景

dongge

anyRTC Native 4.1.0.1与Web SDK 4.0.11上线

anyRTC开发者

学习 WebRTC 语音 直播 sdk

读懂k8s 容器编排控制器 Deployment

Garfield

k8s pod k8s入门

数字资产钱包开发,数字加密货币app搭建

13530558032

Cassandra Gossip协议的二三事儿

华为云开发者社区

源码 三次握手 开发者 Cassandra Gossip协议

案例分享丨红外自动感应门设计与实现详解

华为云开发者社区

物联网 传感器 感应探测器 SMT32处理器 感应门

数字货币交易平台源码,数字货币交易所开发核心功能

13530558032

FlinkX 如何读取和写入 Clickhouse?

Apache Flink

flink

MAC系统初始化

焦振清

macos 重装系统

LeetCode题解:155. 最小栈,单个栈存储入栈元素与最小值之差,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

技术分享:即构互动白板音视频同步、多端有序协作技术实践

ZEGO即构

音视频 在线教育 SVG

融云Geek Online 2020 编程挑战赛重磅来袭

InfoQ_967a83c6d0d7

凡泰极客与Rancher达成深度战略合作,加速企业构建私有化小程序生态

fino星君

3种双集群系统方案设计模式详解

华为云开发者社区

数据库 数据仓库 数据 双集群系统 双ETL模式

深圳泰利能源有限公司涉嫌传销 共计2.7亿元

CECBC区块链专委会

区块链 基金

从 Node.js(JavaScript) 到 Golang,我的开发体验

Garfield

go node.js golang新手

区块链助力军事人力资源配置

CECBC区块链专委会

区块链 军事

「中国技术开放日·长沙站」现场直播

「中国技术开放日·长沙站」现场直播

于我而言,Go语言是新的Ruby-InfoQ