导入路径应该是全局唯一的,因此使用源存储库的路径作为其基础。例如,go.net 子存储库中的 websocket 包的导入路径为golang.org/x/net/websocket。Go 项目拥有路径github.com/golang,因此该路径不能被其他作者用于不同的包.由于存储库 URL 和导入路径相同,因此 go get 命令可以自动获取和安装包。
如果你不使用托管源存储库,请选择一些唯一前缀,如:域、公司或项目名称。例如,所有 Google 内部 Go 代码的导入路径都以字符串“google”开头。
有时人们将 GOPATH 设置为其源存储库的根目录,并将他们的包放在相对于存储库根目录的目录中,例如src/my/package,一方面,这使导入路径很短(my/package而不是github.com/me/project/my/package),但另一方面它打破了 go get 并强制用户重新设置他们的 GOPATH使用包装。不要这样做。
最小程度的导出接口
你的代码可能由许多小段有用的代码组成,因此很容易在包的导出接口中公开大部分功能。拒绝这种行为!
你提供的接口越大,你必须支持的越多,用户很快就会依赖于你导出的每一种类型、函数、变量和常量,从而创建一个你必须永久遵守的隐式契约,否则就有破坏用户程序的风险。在准备 Go 1 时,我们仔细审查了标准库的导出接口,并删除了我们尚未准备好提交的部分。在分发自己的库时,也应该采取类似的措施。
[译] 组织GO代码
介绍
Go 代码的组织方式与其他语言不同。这篇文章讨论了如何命名和打包 Go 程序的元素以最好地为其用户服务
选择好的命名
选择的名称会影响对代码的看法,因此在命名包及其导出的标识符时要小心。 包的名称为其内容提供上下文。例如,标准库中的
bytes
包导出Buffer
类型。就其本身而言,名称Buffer
并不是很具有描述性,但是当结合它的包名称时,它的含义就变得清晰:bytes.Buffer
。如果包的名称不太具有描述性,例如util
,则缓冲区可能会获得更长、更笨拙的名称util.BytesBuffer
。 在工作时不要羞于重命名。 随着花时间在程序上,你将更好地了解它的各个部分如何组合在一起,因此,它们的名称应该是什么。没有必要将自己锁定在早期的决定中。 (gofmt命令具有-r标志,该标志提供了可识别语法的搜索和替换,从而使大规模重构更加容易。) 一个好名字是软件界面最重要的部分:名称是代码的每个客户端都会看到的第一件事。因此,精心挑选的名称是良好文档的起点。以下许多实践都是由良好的命名有机地产生的。选择好的导入路径
导入路径是用户用来导入包的字符串。它指定包的源代码所在的目录(相对于 $GOROOT/src/pkg 或 $GOPATH/src)。
导入路径应该是全局唯一的,因此使用源存储库的路径作为其基础。例如,
go.net
子存储库中的websocket
包的导入路径为golang.org/x/net/websocket
。Go 项目拥有路径github.com/golang
,因此该路径不能被其他作者用于不同的包.由于存储库 URL 和导入路径相同,因此 go get 命令可以自动获取和安装包。如果你不使用托管源存储库,请选择一些唯一前缀,如:域、公司或项目名称。例如,所有 Google 内部 Go 代码的导入路径都以字符串“google”开头。
导入路径的最后一个元素通常与包名称相同。例如,导入路径
net/http
包含程序包http
。这不是必需的,如果你愿意,可以让它们不同,但是为了可预测性,你应该遵循约定:用户可能会惊讶于import "foo/bar"
将标识符quux
引入包名称空间。有时人们将
GOPATH
设置为其源存储库的根目录,并将他们的包放在相对于存储库根目录的目录中,例如src/my/package
,一方面,这使导入路径很短(my/package
而不是github.com/me/project/my/package
),但另一方面它打破了go get
并强制用户重新设置他们的GOPATH
使用包装。不要这样做。最小程度的导出接口
你的代码可能由许多小段有用的代码组成,因此很容易在包的导出接口中公开大部分功能。拒绝这种行为!
你提供的接口越大,你必须支持的越多,用户很快就会依赖于你导出的每一种类型、函数、变量和常量,从而创建一个你必须永久遵守的隐式契约,否则就有破坏用户程序的风险。在准备 Go 1 时,我们仔细审查了标准库的导出接口,并删除了我们尚未准备好提交的部分。在分发自己的库时,也应该采取类似的措施。
如果有疑问,请忽略它!
包里面放什么
很容易把所有东西都扔进一个垃圾包里,但又淡化了包名的含义(因为它必须包含很多功能)并迫使包中小部分的用户编译和链接许多不相关的代码。 另一方面,也很容易将代码拆分成过多小包,在这种情况下,你可能会陷入接口设计的泥潭,而不仅仅是完成工作。
请参阅Go标准库作为指南。它的一些包很大,一些很小。例如,
http
包包含 17 个 go 源文件(不包括测试)并导出 109 个接口,而hash
包包含一个仅导出三个声明的文件。没有硬性规定;鉴于其背景,这两种方法都是合适的。话虽如此,包
main
通常比其他包大。复杂的命令包含许多在可执行文件的上下文之外几乎没有用的代码,通常将它们全部放在一个地方更简单。例如,go 工具有 12000 多行,分布在 34 个文件中。代码文档化
良好的文档是可用和可维护代码的基本质量。阅读Godoc:记录Go代码文章,了解如何编写好的文档注释。