Go 简单性的价值:来自对 Go 倍加青睐的谷歌软件工程师的自述

Go 简单性的价值:来自对 Go 倍加青睐的谷歌软件工程师的自述

Go 语言最近几年逐渐获得越来越多的开发者的喜欢。在 Go 社区前不久刚刚庆祝Go诞生10周年生日之际,谷歌云软件工程师 Benjamin Congdon 发表个人博客(11 月 11 日发表),表达了自己对 Go 倍加青睐的一些原因。他表示,“简洁”是他喜欢使用Go语言最重要的原因。原文链接:https://benjamincongdon.me/blog/2019/11/11/The-Value-in-Gos-Simplicity/

以下是译文:

使用 Go 几年后,我真的很欣赏它的简单性。 我几个月前开始在工作中使用 Go,发现它真的很容易实现迭代,甚至是比 Python 和 Java 更为复杂的迭代。

当 Go 社区庆祝其成立 10 周年 时,我正在思考是什么使 Go 变得独一无二。 我认为 Go 的许多真正力量来自其设计师的理念:高度强调向前兼容性,该语言没有损害可读性的特性,并且随手可得。 你真正需要的一切它都提供了(包括基本测试库,可靠的联网和同步原语以及模板等)。

向前兼容性和依赖性

我认为,相较近期的语言,Go 具有最完善的版本控制和依赖关系。 我从未因为 Go 的版本更新而遇到破坏兼容性的情况。 这很重要。 在相似的时间段内,由于 Rust 的 API 更改,臭名昭著的 Python 2 到 3 过渡,我的项目中断了,老实说,如果 npm 升级后我的任何旧 JS 项目让我感到吃惊。

借助 Go,我注意到库趋于稳定,这似乎让人担忧。 因为在 Python 和 JavaScript 领域,如果你看到 3 年未更新的库,则表明该库已死。 而在 Go 生态系统中,你可能可以使用它。 在其他社区中被视为停滞或忽视的事物,在 Go 这里反而是复兴的标志。

我还注意到,在 Go 中,我需要更少的依赖项,而我的依赖项本身也具有更少的依赖项。 Go 没有将尽可能多的逻辑导出到外部依赖项的文化。 Go 社区比其他地方更容易接受代码重复。 这可能令人沮丧。 有时,你只想要一个执行某种类型的环境或分析的库。 很多时候,你需要自己编写该功能,或者从 StackOverflow 答案中复制/粘贴该功能。 总的来说,我认为这一点还是利大于弊。更少的依赖项意味着项目闲置几个月之后被迫中断的可能性更低。

现在,这对于其他语言、社区可能有点不公平。 Rust 尚未达到 Go 所具有的稳定性,这可能是因为它还不是一种成熟的语言,但它正朝着这一方向发展。 Python 3 本身已向前兼容,我希望 Python 核心开发人员能从中学到关于硬破损的教训。 在这方面,我对 Javascript 不太抱有希望,但是据说 WebAssembly 和 ES10 将解决我们所有的问题。

Go 的依赖管理并不是没有问题。 有一阵子,depglide 的破裂确实很烦人。 并且,尽管 Go Modules 很棒,但社区仍未达到 100% 的采用率。 在使用 Go Modules 之前,将所有内容都保留在 $GOPATH 下的要求非常烦人,以至于我推迟了多年进入 Go 的工作。 现在情况已经好转并显示出改善的迹象。

就向前兼容性而言,自 Go1 发布以来,所有 Go 代码都可以得到兼容性的保证,这会一直运行到 Go2,直到将来的某个不确定的时间点。 这是一个强有力的承诺,至少到目前为止,这让我对这种语言的使用很放心。

“你不需要它”(但你可能想要它)

在使用 Go 一段时间后,我开始想要一些Go语言根本不支持的额外功能。 嗯,我对 C++ 模板的排斥程度不亚于任何一个人,但是拥有基本的集合类泛型这个要求也不过分,对吧?

开箱即用的唯一两个通用数据结构是切片(slice)和映射(map)。那是否要编写自己的数据结构?要么必须针对特定类型进行设置,要么需要盯着一个全是 interface{} 的字段。这两种方法都各有所长,但有时候,我希望可以只导入类型安全的、通用的、双向 map。

Go 将“你根本不需要”发挥到了极致。“需要”是这里的重点词。你“不需要”泛型,但几乎可以肯定你想要它。这样的语法糖在错误处理、函数式编程和运算符重载上都是上上之选。

那句“陈词滥调”怎么说来着?有时“少即是多”。除了命名返回值之外,我想不出 Go 语言中的任何让用户抓狂的功能了。令人印象深刻的是,Go 核心开发人员对在 Go 中模仿其他语言的开发人员群体表现出了极大了约束。Go2 的未来对我来说真的很令人兴奋,因为我很期待看到已经习惯的“下一代” Go 是什么样子。

包括了足够你需要的

对于 Go 令人赞叹的另一点是,它提供了几乎所有你需要的。

go test 是一个很好的(尽管是基本的)测试框架。 你无需成为 JUnit 的领域专家,也无需在 noseunittest 之间进行选择。 为方便起见,有一些测试断言库,例如 testify,你可以引入它们,但“你并不必须要”。

类似地,Go 的 sync 包涵盖了你可能需要的大多数同步原语,http提供了可用于生产环境的 HTTP 服务器和客户端(甚至支持 HTTP2),而且 encoding 包有足够多的子包可以处理 json、xml、csv 以及许多其他常见格式的数据。

格式化,格式化,格式化(老外也强调重要的事情说三遍)

最后,如果我不提到gofmt,我会很失落。 在格式化方面,我有点挑剔。 我并不特别在意使用哪些规则,但是我非常在乎一致性。 Go 的内部格式化工具 gofmt 已被社区广泛采用,并提供了足够的一致性,使 Go 的代码“看起来”符合 Go 的习语,而不会看代码看得要抓狂。

就个人而言,我发现使用gofmt可以更轻松地阅读开源 Go 代码。每个项目仍然有自己的处理方式,但是每个项目都遵循相同的格式约定。 从美学上讲,这让人很高兴。


所以,我喜欢 Go。 曾经有一段时间,我对 Zen of Python 非常着迷,并且对其他语言不屑一顾。我期待 Go 的美好未来,我可能以后会在 Rust 流行起来之后,去用 Rust 赶一波时髦,因为我确实喜欢一些类似于函数式的编程。

但是现在,我非常愿意继续使用 Go 语言。

欢迎关注我的公众号:

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据