我努力尊重每个人的个人喜好,所以我通常会避开关于哪种是最好的编程语言、文本编辑器或操作系统的辩论。
然而,最近我被问到了几次为什么我喜欢和大量使用 Go,所以这是一个连贯的文章,可以填补我临时当面胡诌的空白 :-)。
我的背景
我曾用 C 和 Perl 语言写过一些大型项目。 我也同时使用 Python、Ruby、C ++、CHICKEN Scheme、Emacs Lisp、Rust 和 Java(仅用于 Android )编写程序。 我了解一点 Lua、PHP、Erlang 和 Haskell。 在更之前的生活中,我使用 Delphi 开发过许多程序。
在 2009 年 Go 刚发布的时候,我对它有过短暂的了解。2012 年 Go 1.0 发布时,我开始认真地使用这门语言,因为它具有 Go 1 的兼容性保证。我仍然有 2012 年编写的代码在生产中运行,基本上没有动过。。
1. 清晰
格式化
按照惯例,使用 gofmt 工具格式化代码。 程序格式化代码不是一个新的想法,但与其之前的编程语言不同的是, gofmt
恰恰只支持一种规范风格。
所有代码的格式都是一样的,这使得阅读代码更容易;代码感觉很熟悉。这不仅在阅读标准库或 Go 编译器时有帮助,而且在与许多代码库一起工作时也有帮助--尤其考虑到开源,或大公司。
此外,自动格式化在代码审查中是一个巨大的时间节省,因为它消除了以前可以审查代码的整个维度:现在,你可以只让你的持续集成系统验证 gofmt
没有产生差异。
有趣的是,让我的编辑器在保存文件时应用 gofmt
,改变了我写代码的方式。我曾经试图与格式化器所执行的内容相匹配,然后让它纠正我的错误。现在,我尽可能快地表达我的想法,并相信 gofmt
会让它变得漂亮(我输入的 例子,点击 Format )。
高质量代码
到目前为止,我所读过的所有标准库代码质量都非常高。
一个示例是 image/jpeg 包:我当时不知道 JPEG 如何在此时工作,但通过在 维基百科 JPEG 文章和 image/jpeg
代码之间的切换,很容易就能掌握。 如果这个包有更多的注释,我会把它作为一个教学的示例。
观点
我已经同意 Go 社区持有的许多观点,例如:
- 变量名称应该命名短一点,但如果变量使用离其声明越远,命名越要表达出更多的描述性。
- 让依赖树依赖更小点(以合理的程度): 少量复制比少量依赖更好
- 引入抽象层是有代价的。 Go 代码通常很清晰,但清晰的代价是有时会重复。
- 更多内容请参见 CodeReviewComments 和 Go Proverbs 。
较少的关键字和抽象层
Go 规范只列出了 25 个关键字,我可以很容易地把这些关键词记在脑子里。
根据我的经验,少量的抽象层和概念使得这门语言容易上手,并容易适应。
在我们谈论这个问题的时候:我对 GO 规范的可读性感到惊讶。 它似乎真的以程序员为目标(而不是标准委员会?)。
2. 快速
快反馈/低延时
我喜欢快速反馈。我欣赏快速加载的网站,我更喜欢流畅的用户界面,不延迟,我随时都会选择一个快速的工具而不是一个更强大的工具。大型网站的 调查结果发现,大多数人都有这种想法。
Go 编译器的作者尊重我对低延迟的渴望:编译速度对他们来说很重要,新的优化会被仔细评估权衡,优化是否会降低编译速度。
我的一个朋友以前没有使用过 Go 。在使用 go get
安装了 RobustIRC 之后,他们得出结论,Go 一定是一种解释语言,我不得不纠正他们:不,Go的编译器就是这么快。
大多数 Go 工具也不例外,例如 gofmt
或 goimports
都快得惊人。
资源使用量最大化
对于批处理程序(相对于互动程序而言),充分利用可用资源通常比低延迟更重要。
剖析和改变Go程序以利用所有可用的 IOPS 、网络带宽或计算能力是非常容易的。举个例子,我写过填补1 Gbps 的 链接,并优化了 debiman 以利用所有可用资源,使其运行时间减少了几个小时。
3. 丰富的标准库
Go 标准库提供了有效使用常见通信协议和数据存储格式/机制的手段,如TCP/IP、HTTP、JPEG、SQL、...
Go 的标准库是我见过的最好的库。我认为它组织良好、干净、小而全面:我经常发现只用标准库和一两个外部包就可以写出合理规模的程序。
特定领域的数据类型和算法(一般来说)不包括在标准库,例如 golang.org/x/net/html 。golang.org/x
命名空间也是新代码进入标准库之前的一个暂存区域:Go 1的兼容性保证排除了任何破坏性的改变,即使它们显然是值得的。一个突出的例子是 golang.org/x/crypto/ssh
,它不得不破坏现有的代码以 建立一个更安全的默认值。
4. 工具
为了下载、编译、安装和更新Go软件包,我使用 go get
工具。
我所使用的所有 Go 代码库都使用了内置的 测试设施。这不仅使测试变得简单而快速,而且 覆盖率报告也很容易得到。
每当一个程序使用的资源超过预期,我就会启动 pprof
。关于 pprof 的介绍,请看 golang.org 的这篇 博文,或者我关于优化 Debian Code Search 的 文章。在导入 net/http/pprof 包之后,你可以在你的服务器运行时对其进行剖析,而无需重新编译或重新启动。
交叉编译就像设置 GOARCH
环境变量一样简单,例如,GOARCH=arm64
用于针对 Raspberry Pi 3 的编译。值得注意的是,工具也可以跨平台工作。例如,我可以在我的 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 slack 频道时指出的 初学者资源。见 https://golang.org/help/。
注意事项
当然,没有哪个编程工具是完全没有问题的。鉴于这篇文章解释了为什么 Go 是我最喜欢的编程语言,它的重点是积极的一面。不过,我还是要顺便提一下几个问题。