菜单

包目录 (/pkg)

相关源文件

/pkg 目录是 Go 项目布局中的一个标准目录,用于存放供外部应用程序使用的库代码。本页面将解释在 Go 项目结构中使用 /pkg 目录的目的、约定和最佳实践。

有关不用于外部使用的私有应用程序代码的信息,请参阅内部目录页面 内部目录 (/internal)

目的与作用

/pkg 目录是明确设计用于外部使用的公共库和包的存放地。将代码放置在此目录中,即表明

  1. 代码足够稳定,可供外部使用
  2. 其他项目可以安全地导入和使用这些库
  3. 由于存在外部依赖,破坏性更改将受到仔细考虑

此目录在面向公众的代码与应用程序的内部实现细节之间创建了清晰的界限。

来源: README.md78-88 pkg/README.md1-11

与内部目录的比较

/pkg/internal 之间的关键区别在于代码的可见性和可导入性

目录目的编译器强制性目标受众
/pkg公共库无编译器限制外部项目和应用程序
/internal私有代码Go 编译器阻止外部导入仅限当前项目

/internal 目录提供编译器强制的私有性,而 /pkg 目录依赖约定来传达公共 API 的意图。

来源: README.md78-88 pkg/README.md1-11 internal/README.md1-5

使用约定

何时使用 /pkg

当您在以下情况时,可以考虑使用 /pkg 目录:

  1. 您正在开发应供外部项目使用的库
  2. 您的项目规模庞大,包含许多组件,并且您希望清晰地标识面向公众的代码
  3. 您的根目录包含许多非 Go 组件,并且您希望将 Go 代码分组在一起

何时不使用 /pkg

当以下情况时,/pkg 目录可能不是必需的:

  1. 您的项目规模较小或是一个简单的应用程序
  2. 您的所有代码都打算为您的应用程序私有
  3. 您偏爱更扁平的项目结构

/pkg 内的包组织

/pkg 目录中,包通常按域或功能进行组织。每个公共库通常都有自己的目录。

来源: README.md78-88 pkg/README.md3-5

历史背景

/pkg 目录模式起源于 Go 早期源代码本身,该代码在其包中使用了此目录。随着时间的推移,Go 生态系统中的许多项目都采用了这种模式。

值得注意的是,这种模式不是 Go 团队定义的官方标准,在 Go 社区中也不是普遍接受的。一些 Go 开发人员更喜欢替代结构,但 /pkg 仍然是组织面向公众代码的常见且可识别的约定。

来源: README.md88 pkg/README.md10-11

公共代码注意事项

当将代码放置在 /pkg 目录时,请考虑以下几点:

  1. API 稳定性/pkg 中的代码意味着致力于维护向后兼容性
  2. 文档:公共库应为外部用户提供充分的文档
  3. 测试:全面的测试对于其他项目将依赖的库至关重要
  4. 版本控制:考虑使用语义版本控制来传达重大更改

来源: README.md78-82 pkg/README.md3-5

实际应用示例

/pkg 目录被许多流行的 Go 项目使用,包括:

  • Kubernetes
  • Docker (Moby)
  • Helm
  • Prometheus
  • Grafana
  • InfluxDB
  • CockroachDB
  • Istio

这些项目展示了 /pkg 目录在公共库和组件方面的有效使用。

来源: pkg/README.md14-112

与其他目录的关系

/pkg 目录与 Go 标准项目布局中的其他目录协同工作

来源: README.md58-88 pkg/README.md1-11

总结

/pkg 目录是 Go 标准项目布局中用于组织面向公众的库和包的关键组成部分。虽然 Go 编译器不强制执行,也不是普遍接受的,但它为沟通代码库哪些部分是为外部使用而设计的提供了一个清晰的约定。

对于同时包含私有和公共组件的大型项目,同时使用 /internal/pkg 目录可以实现关注点分离,并向代码的贡献者和外部用户传达意图。