4. 项目的目录结构
Go 项目的目录结构, 通常都会参考该项目 Go语言规范/项目结构 - Github 。
这是一个社区规范, 遵守这个规范, 大家都会很轻松。 但并不是严格的 Go 语言标准, 实际操作中各个公司可能会有自己的标准。
另外, 在上述的 Github 仓库中可以看到, 所有 目录功能 都只有一层。 这样就意味着在实际使用时我们是可以自由组合。 只要遵守该层的功能约定就可以了。
例如, 使用 cobra 时, 用于管理命令的 cmd
目录, 位置可以是
/cmd/appname/cmd
# 或
/pkg/cmd/
# 或
/internal/pkg/cmd
# 或
/pkg/internal/cmd
关于这个没有必要钻牛角尖, 只要是一群相对固定的维护人员认同的约定, 就可以了。
internal
包是是特殊的, 也是 Go 语言规范 强制 约束的。
- 首先, 它的目录位置不是固定的, 和其他包一样。
- 其次, 它的访问是受限的, 只有和他有 近亲亲属关系 的路径才能访问。
举个例子, 代码在 https://github.com/tangx-labs/go-internal-demo
代码目录树如下
在上图中, 其中 (2) 的调用因为没有权限被限制
在 /cmd/appname/cmd/say
访问 pkg/internal/master
时,
- 找到与
/pkg
与/cmd
是相同层级。 - 但是
/pkg/internal
是子层级, 与/cmd/appname
是同一层级。 - 因此属于 远亲, 不能直接调用
/pkg/internal/master
但是, 可以通过 私有包的公共方法暴露, 例如上图中的 (3)
/pkg/hello
与/pkg/internal
是同级, 且是 近亲, 可以调用。/pkg/hello
是公共的/cmd/appname/cmd/say
可以通过调用/pkg/hello
间接实现调用 master 的逻辑。(
更多详细信息, 可以阅读 internal 运行机制
那 internal 是不是就一定不能被访问了呢? 也不一定, 可以参考 突破限制,访问其它Go package中的私有函数
关于包的命名规范, Go 官方是有明确说明的, 但是 没有强制约束 。
要求
- 短,好记,有意义:
bytes, io, os
- 小写字母。 多个单词使用 连字符(-) 连接, 不要使用 蛇形(下划线) 或者 驼峰:
qcloud-cdn-sdk
更多信息, 参考 effective_go
- 大写开头是公共, 小写开头是私有: 这个就不多说了
- 命名不要与包名有重复: 假如包名为
bytes
, - 函数名就不用叫
BytesReader
了, 否则调用起来就是bytes.BytesReader
。 - 函数名就叫
Reader
就好了, 调用起来就是bytes.Reader
。 - 命令要有意义: 见名知义。
- 命名要遵循 驼峰 规则。
这个就不多说了, 学了基础的都应该知道, 相关文章一搜一大把。
这个是 Go 语言的 强制约束。 换句话说, 不用等到编译, 在写代码的时候 IDE 就会提示你出现错误。