我努力尊重每个人的个人喜好,因此我通常会避免争论哪种语言是最佳的编程语言,文本编辑器或操作系统。

但是,最近有几次我被问到为什么我喜欢并使用很多Go,所以这里有一篇连贯的文章来填补我的即席亲自杂谈的空白:-)。

我的背景

我已经在许多体面的项目中使用了C和Perl。我用Python,Ruby,C ++,CHICKEN Scheme,Emacs Lisp,Rust和Java(仅适用于Android)编写程序。我了解一些Lua,PHP,Erlang和Haskell。在前世,我使用Delphi开发了许多程序 。

1.清晰度

格式设定

按照惯例,使用该gofmt工具格式化Go代码 。以编程方式格式化代码不是一个新主意,但是与它的前辈相反,它仅gofmt支持一种规范样式。

以相同的方式格式化所有代码,使阅读代码更容易。该代码感觉很熟悉。这不仅在阅读标准库或Go编译器时有所帮助,而且在处理许多代码库(例如开源或大公司)时也有帮助。

此外,自动格式化在代码检查期间可以节省大量时间,因为它消除了以前可以检查代码的整个维度:现在,您只需让您的持续集成系统验证不会gofmt产生差异即可。

有趣的是,gofmt保存文件时让我的编辑器生效已经改变了我编写代码的方式。我曾经尝试匹配格式化程序将要执行的操作,然后让它纠正我的错误。如今,我尽可能快地表达自己的想法,并相信gofmt可以使它变得漂亮(例如,键入内容,请单击“格式”)。

高质量代码

我使用了很多标准库(docs, source),请参见下文。

到目前为止,我阅读的所有标准库代码都是非常高质量的。

一个例子是image/jpeg程序包:当时我还不知道JPEG的工作方式,但是通过在Wikipedia JPEG文章和 image/jpeg代码之间进行切换很容易实现。如果该软件包还有其他意见,我将其视为教学实施。

意见

我已经同意Go社区的许多观点,例如:

  • 默认情况下,变量名应该短一些,并且随着声明使用名称的增加,其名称也变得更具描述性。
  • 保持依赖性树很小(在合理的程度):稍微复制胜于一点依赖性
  • 引入抽象层是有代价的。Go代码通常非常清晰,但有时会有些重复。
  • 有关更多信息,请参见CodeReviewComments和Go Proverbs。

很少的关键字和抽象层

Go规范仅列出了25个关键字,我可以很容易地记住这些关键字。

内置函数和 类型也是如此。

以我的经验,少量的抽象层和概念使该语言易于学习,并很快就感到舒适。

当我们谈论它时:我对Go规范的可读性感到惊讶。它似乎真的是针对程序员(而不是标准委员会)。

2.速度

快速反馈/低延迟

我喜欢快速的反馈意见:我希望网站能够快速加载,我更喜欢流畅的用户界面,它们不会滞后,而且我会每天选择快速工具,而不是功能更强大的工具。 大型网络媒体资源的调查结果证实,此行为是许多人共有的。

Go编译器的作者尊重我对低延迟的渴望:编译速度对他们很重要,新的优化方案会仔细权衡它们是否会减慢编译速度。

我的一个朋友以前没有使用过Go。在使用安装了RobustIRC桥之后编译了下,他们得出结论,Go必须是一种解释语言,我必须对其进行更正:不,Go编译器就这么快。

大多数Go工具也不例外,例如gofmt,goimports速度非常快。

最大资源使用

对于批处理应用程序(与交互式应用程序相反),充分利用可用资源通常比低延迟更为重要。

配置和更改Go程序以利用所有可用的IOPS,网络带宽或计算非常容易。例如,我写了有关 填充1 Gbps链路的信息,并优化了debiman以利用所有可用资源,从而将其运行时间减少了数小时。

3.丰富的标准库

在围棋标准库提供了手段,有效地使用公共通信协议和数据存储格式/机制,如TCP / IP,HTTP,JPEG,SQL,…

Go的标准库是我见过的最好的库。我认为它组织得井井有条,干净,小巧而又全面:我经常发现仅使用标准库以及一个或两个外部程序包就可以编写大小合理的程序。

(通常)不包含特定于域的数据类型和算法,并且不在标准库之内(例如)golang.org/x/net/html。该 golang.org/x命名空间还用作新代码的临时区域进入标准库前:转到1兼容性保证,排除了任何重大的变动,即使他们显然是值得的。一个著名的例子是 golang.org/x/crypto/ssh,它必须破坏现有代码以建立更安全的默认值。

4.工具

要下载,编译,安装和更新Go软件包,我使用了该go get工具。

我使用过的所有Go代码库都使用内置 testing功能。这不仅可以轻松快速地进行测试,还可以轻松获得覆盖率报告。

每当程序使用比预期更多的资源时,我就会启动pprof。请参阅此golang.org博客文章 pprof以获取介绍,或 参阅我的博客文章关于优化Debian Code Search。导入net/http/pprof 软件包后,您可以在服务器运行时对其进行概要分析,而无需重新编译或重新启动。

交叉编译就像设置GOARCH环境变量一样容易,例如GOARCH=arm64,针对Raspberry Pi3。值得注意的是,工具也可以跨平台工作!例如,我可以 从amd64计算机上分析gokrazy:go tool pprof ~/go/bin/linux_arm64/dhcp http://gokrazy:3112/debug/pprof/heap。

godoc将文档显示为纯文本或通过HTTP提供。godoc.org是一个公共实例,但是我运行一个本地实例,以供离线使用或尚未发布的软件包使用。

请注意,这些是语言随附的标准工具。来自C,以上每一项都是一项重要的成就。在Go中,我们认为它们是理所当然的。

入门

希望我能够表达出我对使用Go感到高兴的原因。

如果您有兴趣开始使用Go,请查看 当人们加入Gophers闲暇频道时我们为他们提供的初学者资源。

注意事项

当然,没有编程工具是完全没有问题的。鉴于本文解释了为什么Go是我最喜欢的编程语言,因此将重点放在积极方面。不过,我会顺便提及一些问题:

  • 如果使用不提供稳定API的Go软件包,则可能要使用特定的已知工作版本。最好的选择是dep工具,在撰写本文时,它不属于该语言的一部分。
  • 惯用的Go代码不一定会转换为性能最高的机器代码,并且运行时要付出(小的)代价。在极少数情况下,我发现缺乏性能,因此我成功地求助于cgo或汇编程序。但是,如果您的域是硬实时应用程序或其他对性能至关重要的代码,那么您的工作量可能会有所不同。
  • 我写过Go标准库是我见过的最好的库,但这并不意味着它没有任何问题。一个示例是在通过标准库最旧的软件包之一以编程方式修改Go代码时对注释的复杂处理go/ast。