模块课程(4/5)
Go 模块
Go 模块 是由一个或多个包组成的可版本化单元。它是现代依赖系统(Go 1.11+)的基础:不再有 GOPATH,不再有强制的 vendor,显式且可重现的依赖关系。
go.mod:模块清单
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 命令自动更新。
基本命令
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 graphgo 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。
import "github.com/foo/bar/v2"这使您可以同时导入同一库的 v1 和 v2 (在渐进式迁移期间很有用)。
导入路径和内部包
如果您的模块是 example.com/myapp,则 utils/ 子文件夹将导入为:
import "example.com/myapp/utils"该路径仅取决于 go.mod 中声明的名称,而不取决于磁盘上的位置:不同文件夹中的相同代码仍然有效。
工作区模式(Go 1.18+)
要同时处理相互引用的多个模块(例如库和使用它的应用程序):
go work init ./lib ./app这将创建 go.work: go build 将使用 ./lib 的本地版本,而不是下载已发布的版本。 不要提交 go.work (它是一个开发环境)。
练习
该模块是 example.com/myapp 并包含 utils 子文件夹。使用完整路径导入main中的子包。
显示提示
导入路径是模块名称(来自 go.mod)加上文件夹的相对路径。
3 次尝试后可用的解决方案
使用 import ( ... ) 语法将单个导入转为导入组,同时导入 fmt 和 os。
3 次尝试后可用的解决方案
哪个命令删除不再从 go.mod 导入的依赖项并添加缺少的依赖项?
$ go mod ???