首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

于我而言,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/

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/LDICx7lTPDbqp6QGEJhL
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券