- 原文地址:A bird's eye view of Go
- 原文做者:Axel Wagner
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:JackEggie
- 校对者:40m41h42t, JalanJiang
本文摘要:本文很是笼统地总结了 Go 语言的定义、生态系统和实现方式,也尽力给出了与不一样的需求所对应的参考文档,详情参见本文末尾。html
每当咱们提及“Go 语言”的时候,可能会由于场景的不一样聊到不少彻底不一样的东西。所以,我尝试着对 Go 语言和其生态系统作一个概述,并在各部份内容中都列出相关的文档(这可能有点像是大杂烩,其中还包含了我最近实际遇到的许多问题)。让咱们开始吧:前端
Go 语言是一种编程语言。做为一种权威,Go 语言规范中定义了代码的格式规范和代码所表明的含义。不符合该规范的都不是 Go 语言。一样地,该规范中没有提到的内容不视为该语言的一部分。目前由 Go 语言开发团队维护该规范,每半年发布一个新版本。在我写这篇文章的时候最新的版本是 1.12
。android
Go 语言规范规定了:ios
该规范应该已经足够让你实现一个 Go 语言的编译器了。实际上,已经有不少人基于此实现了许多不一样的编译器。git
该语言规范只是一份文本文档,它自己不太有用。你须要的是实现了这些语义的软件,即编译器(分析、检查源代码,并将其转换为可执行的形式)和运行时(提供运行代码时所需的环境)。有不少这样的软件组合,他们都或多或少有些不一样。示例以下:程序员
gc
,Go 语言开发团队本身开发的纯 Go 语言实现的(有一小部分汇编实现)编译器和运行时。它随着 Go 语言一块儿发布。与其余此类工具不一样的是,gc
并不严格区分编译器、组装器和连接器 —— 它们在实现的时候共享了大量的代码,而且会共享或传递一些重要职责。所以,一般没法连接由不一样版本的 gc
所编译的包。gc
得到了 WebAssembly 的原生支持,它有可能会被淘汰。还有更多其余的实现,但这已经足以让你了解不一样的实现方式。以上每一种方法都使用了不一样的方式来实现 Go 语言,并具备本身不同凡响的特性。他们可能存在的不一样之处有(为了说明这一点,下面的某些说法可能会有点奇特):github
int
/uint
的大小 —— 长度可能为 32 位或 64 位。map
的顺序并无在 Go 语言中定义 —— gc
显然会将这类操做随机化,而 gopherjs
会用你使用的 JavaScript 实现遍历。append
操做分配的所需额外内存空间大小 —— 可是,在分配额外空间时,不会再次分配更多的内存空间。unsafe.Pointer
与 uintptr
之间的转换方式。特别指出,gc
对于该转换什么时候应该生效有本身的规则。一般状况下,unsafe
包是虚拟的,它会在编译器中被实现。通常来讲,根据规范中没有提到的某些细节(尤为是上面提到的那些细节)可使你的程序用不一样的编译器也能编译,但每每程序不会像你预期的那样正常工做。所以,你应该尽力避免此类事情发生。golang
若是你的 Go 语言是经过“正常”渠道安装的话(在官网上下载安装,或是经过软件包管理器安装),那么你会获得 Go 开发团队提供的 gc
和正式的运行时。在本文中,当咱们在讨论“Go 是如何作的”时,若没有在上下文特别指明,咱们一般就是在谈论 gc
。由于它是最重要的一个实现。编程
标准库是 Go 语言中附带的一组依赖包,它能够被用来当即构建许多实用的应用程序。它也由 Go 开发团队维护,而且会随着 Go 语言和编译器一块儿发布。通常来讲,标准库的某种实现只能依赖与其共同发布的编译器才能正常使用。由于大部分(但不是全部)运行时都是标准库的一部分(主要包含在 runtime
、reflect
、syscall
包中)。因为编译器在编译时须要兼容当前使用的运行时,所以它们的版本要相同。标准库的 API 是稳定的,不会以不兼容的方式改变,因此基于某个指定版本的标准库编写的 Go 程序在编译器的将来版本中也能够正常运行。c#
有些标准库会彻底本身实现整个库中的全部内容,而有些则只实现一部分 —— 开发者尤为会在 runtime
、reflect
、unsafe
和 syscall
包中实现自定义的功能。举个例子,我相信 AppEngine 标准库是出于安全考虑从新实现了标准库的部分功能的。这类从新实现的部分一般会尽可能对用户保持透明。
还存在一种标准库之外的独立库,通俗地说这就是 x
或者说是“扩展库”。这种库包含了 Go 开发团队同时开发和维护的部分代码,可是不会与 Go 语言有相同的发布周期,而且相比于 Go 语言自己,兼容性也会较差(功能性和维护性也会较差)。其中的代码要么是实验性的(在将来可能会包含在标准库中),要么是比起标准库中的功能还不够泛用,或者是在某些罕见的状况下,提供一种开发者们能够与 Go 开发团队同步进行代码审查的方式。
再一次强调,若是没有额外地指出,在提到“标准库”时,咱们指的是官方维护和发布的、托管在 golang.org 上的 Go 标准库。
咱们须要代码构建工具来使 Go 语言易于使用。构建工具的主要职责是找到须要编译的包和全部的依赖项,并依据必要的参数调用编译器和连接器。Go 语言有对包的支持,容许在编译时把多个源代码文件视为一个单元。这也定义了导入和使用其余包的方式。但重要的是,这并无定义导入包的路径与源文件的映射方式,也没有定义导入包在磁盘中的位置。所以,每种构建工具对于该问题都有不一样的处理方式。你可使用通用构建工具(如 Make 命令),但也有许多专门为 Go 语言而生的构建工具:
gc
和标准库)有相同的发布周期。它须要一个名为 GOROOT
的目录(该值从环境变量中获取,会在安装时产生一个默认值)来存放编译器、标准库和其余各类工具。它要求全部的源代码都要存放在一个名为 GOPATH
的目录下(该值也从环境变量中获取,默认为 $HOME/go
或是一个与其相等的值)。举例来讲,包 a/b
的源代码应该位于诸如 $GOPATH/src/a/b/c.go
的路径下。而且 $GOPATH/src/a/b
路径下应该只包含一个包下的源文件。在分布式的模式下,有一种机制能够从任意服务器上递归地下载某个包及其依赖项,即便这种机制不支持版本控制或是下载校验。Go 语言工具中也包含了许多其余工具包,包括用于测试 Go 代码的工具、阅读文档的工具(golang.org 是用 Go 语言工具部署的)、提交 bug 的工具和其余各类小工具。代码构建工具是大多数用户在编写代码时直接使用的重要工具,所以它很大程度上决定了 Go 语言生态系统的方方面面,也决定了包的组合方式,这也将影响 Go 程序员之间的沟通和交流方式。如上所述,Go 语言工具是被隐式引用的(除非指定了其余的运行环境),所以它的设计会让公众对 “Go 语言”的见解形成很大的影响。虽然有许多替代工具可供使用,这些工具也已经在如公司内部使用等场景被普遍使用,可是开源社区一般但愿 Go 语言工具与 Go 语言的使用方式相契合,这意味着:
go test
运行测试。go build
来编译(与后面所述的特征共同被称为“能够经过 Go 获得的” —— “go-gettable”)。特别指出,若是须要生成源代码或是元编程,则使用 go generate 并提交生成的构件。Go 语言工具的文档很是全面,它是一个学习 Go 如何实现各类生态系统的良好起点。
Go 语言的标准库包含了一些能够与 Go 源代码交互的包和包含了更多功能的 x/tools 扩展库。Go 语言也所以在社区中有很是强的第三方工具开发文化(因为官方强烈地想要保持 Go 语言自己的精简)。这些工具一般须要知道源代码的位置,可能还须要获取类型信息。go/build 包遵循了 Go 语言工具的约定,所以它自己就能够做为其部分构建过程的文档。缺点则是,构建在它之上的工具备时与基于其余构建工具的代码不兼容。所以有一个新的包正在开发中,它能够与其余构建工具很好地集成。
实际上 Go 语言的工具备很是多,而且每一个人都有本身的偏好。但大体以下:
go tool <cmd>
命令来访问。我想用一个简短的参考文献列表来结束这篇文章,列表的内容是为那些感到迷茫的初学者准备的。请点击下面的连接:
go help
查看。有时会涉及到其余内容,你也能够查看这些不够精细的内容。除此之外还有许多有价值的文档能够做为补充,但这些应该已经足够让你有一个良好的开端了。做为一个 Go 语言的初学者,若是你发现本文有任何遗漏之处(我可能会补充更多的细节)或者你找到了任何有价值的参考资料,请经过 Twitter 联系我。若是你已是一个经验丰富的 Go 语言开发者,而且你发现我遗漏了某些重要的内容(可是我有意忽略了一些重要的参考资料,使得初学者们能够感觉到 Go 语言学习中的新鲜感:smile:),也请给我留言。
[1] 注:Go 开发团队目前正在对模块作一些支持,模块是包之上的代码分发单元,这些支持包括版本控制和一些可使“传统” Go 语言工具解决问题的基础工做。等这些支持完成之后,这一段中的全部内容基本上就都过期了。对模块的支持目前是有的,但还不是 Go 语言的一部分。因为本文的核心内容是对 Go 语言的不一样组成部分进行简要介绍,这些内容是不太容易发生变化的,目前来看我认为理解这些历史问题也是颇有必要的。
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。