DevopsCamp 第 2 期作业: 《cobra - 04 Go 项目的目录结构》

原文链接: https://typonotes.com/posts/2023/02/13/devopscamp-cobra-05-layout/

Go 项目的目录结构

Go 项目的目录结构, 通常都会参考该项目 Go语言规范/项目结构 - Github

这是一个社区规范, 遵守这个规范, 大家都会很轻松。 但并不是严格的 Go 语言标准, 实际操作中各个公司可能会有自己的标准。

另外, 在上述的 Github 仓库中可以看到, 所有 目录功能 都只有一层。 这样就意味着在实际使用时我们是可以自由组合。 只要遵守该层的功能约定就可以了。

例如, 使用 cobra 时, 用于管理命令的 cmd 目录, 位置可以是

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/cmd/appname/cmd

# 或
/pkg/cmd/

# 或
/internal/pkg/cmd

# 或
/pkg/internal/cmd

关于这个没有必要钻牛角尖, 只要是一群相对固定的维护人员认同的约定, 就可以了。

internal

internal 包是是特殊的, 也是 Go 语言规范 强制 约束的。

  1. 首先, 它的目录位置不是固定的, 和其他包一样。
  2. 其次, 它的访问是受限的, 只有和他有 近亲亲属关系 的路径才能访问。

举个例子, 代码在 https://github.com/tangx-labs/go-internal-demo

代码目录树如下

限制访问

在上图中, 其中 (2) 的调用因为没有权限被限制

/cmd/appname/cmd/say 访问 pkg/internal/master 时,

  1. 找到与 /pkg/cmd 是相同层级。
  2. 但是 /pkg/internal 是子层级, 与 /cmd/appname 是同一层级。
  3. 因此属于 远亲, 不能直接调用 /pkg/internal/master

公共方法暴露

但是, 可以通过 私有包的公共方法暴露, 例如上图中的 (3)

  1. /pkg/hello/pkg/internal 是同级, 且是 近亲, 可以调用。
  2. /pkg/hello 是公共的
  3. /cmd/appname/cmd/say 可以通过调用 /pkg/hello 间接实现调用 master 的逻辑。(

更多详细信息, 可以阅读 internal 运行机制

那 internal 是不是就一定不能被访问了呢? 也不一定, 可以参考 突破限制,访问其它Go package中的私有函数

包命名规范

关于包的命名规范, Go 官方是有明确说明的, 但是 没有强制约束

要求

  1. 短,好记,有意义bytes, io, os
  2. 小写字母。 多个单词使用 连字符(-) 连接, 不要使用 蛇形(下划线) 或者 驼峰qcloud-cdn-sdk

更多信息, 参考 effective_go

函数/方法,变量命令

  1. 大写开头是公共, 小写开头是私有: 这个就不多说了
  2. 命名不要与包名有重复: 假如包名为 bytes
  3. 函数名就不用叫 BytesReader 了, 否则调用起来就是 bytes.BytesReader
  4. 函数名就叫 Reader 就好了, 调用起来就是 bytes.Reader
  5. 命令要有意义: 见名知义。
  6. 命名要遵循 驼峰 规则。

循环依赖

这个就不多说了, 学了基础的都应该知道, 相关文章一搜一大把。

这个是 Go 语言的 强制约束。 换句话说, 不用等到编译, 在写代码的时候 IDE 就会提示你出现错误。