跳转到主要内容
模块 9 · 第 4 课(共 5)课程中的44/50~12 min
模块课程(4/5)

Go 模块

Go 模块 是由一个或多个包组成的可版本化单元。它是现代依赖系统(Go 1.11+)的基础:不再有 GOPATH,不再有强制的 vendor,显式且可重现的依赖关系。

go.mod:模块清单

Code
module example.com/myapp

go 1.22

require (
    github.com/google/uuid v1.6.0
    golang.org/x/time     v0.5.0
)

三个主要指令:

  • module <path> — 模块的导入路径。所有内部包均作为 example.com/myapp/sub/pkg 导入。它不必是真实的 URL,但要通过 go get 发布,它必须解析。
  • go <version> — 所需的最低 Go 版本(也用于控制允许哪些语言功能,例如 1.23 中的 range-over-func)。
  • require — 与其确切版本的直接依赖关系。

其他指令:replace(用 fork 或本地路径替换 dep)、exclude、retract。

go.sum:加密锁文件

除了 go.mod 之外,go.sum 还包含每个下载版本(包括传递依赖项)的加密哈希。它保证可重复性:如果有人篡改已发布的版本,构建就会失败。

始终提交它。 它由 go 命令自动更新。

基本命令

Bash
go mod init example.com/myapp        # create go.mod
go get github.com/google/uuid        # add the dep at its latest version
go get github.com/google/uuid@v1.5.0 # specific version
go get -u ./...                      # upgrade every dep
go mod tidy                          # remove unused deps, add missing ones
go mod download                      # download everything into the cache
go mod why github.com/x/y            # explain why a dep is included
go mod graph                         # full dependency graph

go mod tidy 是您在每次更改导入后运行的程序:它保证 go.mod 准确反映实际使用的包。

语义导入版本控制 (SIV)

版本遵循 SemVer:v1.2.3 = MAJOR.MINOR.PATCH。有趣的部分是 major v2+:

  • 主要 v0 和 v1 → 正常路径:github.com/foo/bar。
  • 主要 v2 或更高版本 → 路径 包括主要版本:github.com/foo/bar/v2。
Go
import "github.com/foo/bar/v2"

这使您可以同时导入同一库的 v1 和 v2 (在渐进式迁移期间很有用)。

导入路径和内部包

如果您的模块是 example.com/myapp,则 utils/ 子文件夹将导入为:

Go
import "example.com/myapp/utils"

该路径仅取决于 go.mod 中声明的名称,而不取决于磁盘上的位置:不同文件夹中的相同代码仍然有效。

工作区模式(Go 1.18+)

要同时处理相互引用的多个模块(例如库和使用它的应用程序):

Bash
go work init ./lib ./app

这将创建 go.work: go build 将使用 ./lib 的本地版本,而不是下载已发布的版本。 不要提交 go.work (它是一个开发环境)。

练习

锻炼#go.m9.l4.e1
尝试:0加载中...

该模块是 example.com/myapp 并包含 utils 子文件夹。使用完整路径导入main中的子包。

正在加载编辑器...
显示提示

导入路径是模块名称(来自 go.mod)加上文件夹的相对路径。

3 次尝试后可用的解决方案

锻炼#go.m9.l4.e2
尝试:0加载中...

使用 import ( ... ) 语法将单个导入转为导入组,同时导入 fmt 和 os。

正在加载编辑器...

3 次尝试后可用的解决方案

Quiz#go.m9.l4.e3
准备好

哪个命令删除不再从 go.mod 导入的依赖项并添加缺少的依赖项?

Go
$ go mod ???
答案选项