Golang中如何使用根目录下的新文件夹"pkg"
Golang中如何使用根目录下的新文件夹"pkg"
我下载了 Go 1.20 并使用 VS Code 运行了 go mod tidy。随后在根目录(项目级别)创建了一个名为“pkg”的文件夹。我想知道这是否有问题?为什么会这样出现?我应该如何使用它?
func main() {
fmt.Println("hello world")
}
你将所有希望公开的包都放在那里。所谓公开,是指其他人可以导入并使用它们。
更多关于Golang中如何使用根目录下的新文件夹"pkg"的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
由其他仓库外的项目导入
这是否意味着它会自动导入?对所有项目都如此? 还是我必须使用“import…”来避免引入不需要的库?
值得说明的是:所有不在 main 或 internal 目录下的包都是公共包。我个人真的非常非常非常不喜欢这种 pkg 的用法。话虽如此,如果你想在你的仓库中使用它,那也没问题。
我最近几乎只用 VSCode 来编写 Go 代码。这挺有意思的。我以前从未见过这种情况。pkg 目录里有东西吗?
我能想到的另一个可能性是你的 GOPATH 变量设置得有些奇怪:go env GOPATH 的输出是什么?这个路径和你的代码所在位置有什么关系?
我个人真的非常非常非常不喜欢这种
pkg的用法。
我别无选择。在执行 go mod tidy 时,“pkg”文件夹会自动出现。这会不会是 VS Code 的问题?我第一反应是这不对。但它可能有用。目前,它只是一个几乎为空、令人讨厌且我无法永久摆脱的文件夹。
正如 @heidi 所说,将那些可以被仓库外其他项目导入的包放在那里是一种惯例。但这只是一种惯例,众多惯例之一,而非硬性规定。
有关文件夹布局惯例的更多信息,请参见:GitHub - golang-standards/project-layout: Standard Go Project Layout
关于 /pkg 目录的部分:project-layout/pkg at master · golang-standards/project-layout · GitHub
我最近在 Go 语言开发中几乎只使用 VSCode。这很有趣。我以前从未见过这种情况。
pkg目录里有东西吗?

我能想到的另一件事是你的 GOPATH 变量设置得很奇怪:
go env GOPATH的输出是什么?
/Users/sibert/go
…以及这个位置与你的代码位置有什么关系?
它是包含不同项目文件夹的“项目文件夹”。GOPATH 应该是什么?
关于 golang-standards 组织和那个“标准 Go 项目布局”。正如 Russ Cox 所指出的,它根本就不是标准:
github.com/golang-standards/project-layout
这不是一个标准的 Go 项目布局
README 文件清楚地表明这不是官方的,但即使声称“它是 Go 生态系统中一组常见的历史和新兴项目布局模式”也是不准确的。
例如,Go 生态系统中绝大多数包并没有将可导入的包放在
pkg子目录中。更概括地说,这里描述的内容非常复杂,而 Go 代码仓库往往要简单得多。不幸的是,这被当作“golang-standards”提出,而实际上并非如此。我在这里发表评论,是因为我开始看到有人说“你没有使用标准的 Go 项目布局”并链接到这个仓库。
如果它对某些人有效,那很好。但我仍然认为它给 Go 新手带来的困惑多于帮助。
我不建议将你的代码放在与 go env GOPATH 相同的位置。过去你需要这样做,但需要根据包名以一种特殊的方式进行。让我解释一下:这是过去必须采用的方式,但现在情况已经不同了……
假设 ~/go 是你的 GOPATH。你正在处理的包位于 github.com/user/repo,那么为了让 Go 工具链找到它,这个包必须放在 ~/go/src/github.com/user/repo 目录下。
这种方式在像谷歌这样的公司环境中运行良好,但对个人开发者来说就不那么友好了。因此(我暂且忽略为解决此问题而开发的一些工具),最终 Go 团队提出了模块的概念和 go mod 命令,这(以及其他功能)允许你将代码放在文件系统的几乎任何位置。
你当然可以继续使用 ~/go,但我建议将其移到其他地方,这样 pkg 目录(以及其他可能的目录)就不会出现在你的代码目录中了。
func main() {
fmt.Println("hello world")
}
在Go 1.20及更高版本中,根目录下自动生成的pkg文件夹是正常的,这是Go模块缓存的一部分。它用于存储编译后的包文件(.a文件),以加速后续构建过程。
为什么会出现pkg文件夹?
当您运行go mod tidy或任何Go构建命令时,Go工具链会:
- 下载依赖到
$GOPATH/pkg/mod(全局缓存) - 在项目根目录创建
pkg文件夹存储项目自身的编译结果
这是Go 1.20引入的构建缓存改进的一部分,称为"build cache in module mode"。
如何使用它?
您不需要手动操作这个文件夹,Go工具链会自动管理它。但了解其结构有助于调试:
示例:查看pkg内容结构
package main
import (
"fmt"
"io/ioutil"
"path/filepath"
)
func main() {
// 列出pkg目录内容(如果存在)
files, err := ioutil.ReadDir("pkg")
if err == nil {
fmt.Println("pkg目录内容:")
for _, f := range files {
fmt.Printf("- %s\n", f.Name())
// 如果是目录,可以进一步探索
if f.IsDir() {
subFiles, _ := ioutil.ReadDir(filepath.Join("pkg", f.Name()))
for _, sf := range subFiles {
fmt.Printf(" └─ %s\n", sf.Name())
}
}
}
}
}
实际使用场景
当您构建项目时,Go会自动使用pkg中的缓存:
// main.go
package main
import (
"fmt"
"yourmodule/internal/mathutil" // 假设有本地包
)
func main() {
result := mathutil.Add(10, 20)
fmt.Printf("Result: %d\n", result)
}
// internal/mathutil/mathutil.go
package mathutil
func Add(a, b int) int {
return a + b
}
第一次构建后,mathutil包的编译结果会存储在pkg中,后续构建会直接使用缓存。
注意事项
-
不要提交到版本控制:在
.gitignore中添加:/pkg/ -
清理缓存:如果需要清理,可以:
go clean -cache -
目录结构:
pkg文件夹通常包含:pkg/ └── mod/ └── cache/ └── download/ # 下载的依赖 └── 您的平台目录/ # 如linux_amd64/ └── *.a # 编译的包文件
这个机制提高了构建速度,特别是对于大型项目或频繁的增量构建。


