dduo518 / hexo-blog

hexo静态blog点击 https://github.com/chong0808/hexo-blog/issues
3 stars 0 forks source link

[译] 组织GO代码 #42

Open dduo518 opened 3 years ago

dduo518 commented 3 years ago

[译] 组织GO代码

原文:Organizing Go code

介绍

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代码文章,了解如何编写好的文档注释。