引入

包把代码按功能分好了,但真正写项目总会用到第三方库。A 项目用库的 v1 版本,B 项目用 v2 版本,怎么隔离?Go 模块(module)就是用来解决依赖管理的,每个项目一个模块,版本信息清清楚楚记在 go.mod 文件里。

正文

定义

定义

模块(module)是 Go 的依赖管理单元,由 go.mod 文件定义。一个模块就是一个项目,包含模块路径(导入路径前缀)和依赖版本信息。go.sum 记录依赖的校验哈希,保证依赖没被篡改。

语法

# 初始化模块
go mod init example.com/myproject
 
# 整理依赖(添加缺失的、删除不用的)
go mod tidy
 
# 下载依赖到本地缓存
go mod download
 
# 查看依赖树
go mod graph

例子

初始化模块

mkdir myproject && cd myproject
go mod init example.com/myproject

执行后生成 go.mod 文件:

module example.com/myproject

go 1.21

go mod init 后面跟的是模块路径,也就是这个项目里包的导入路径前缀。如果是放到 GitHub 上,一般用 github.com/用户名/项目名

添加依赖

// main.go
package main
 
import (
    "fmt"
    "github.com/google/uuid"
)
 
func main() {
    id := uuid.New()
    fmt.Println(id)
}
go mod tidy

执行 go mod tidy 后,Go 会自动下载 uuid 包并更新 go.mod

module example.com/myproject

go 1.21

require github.com/google/uuid v1.6.0

go.mod 文件

module example.com/myproject

go 1.21

require (
    github.com/gin-gonic/gin v1.9.1
    github.com/google/uuid v1.6.0
)

require (
    github.com/bytedance/sonic v1.9.1 // indirect
    golang.org/x/net v0.17.0 // indirect
)

require直接依赖(项目直接引用的),// indirect间接依赖(直接依赖所依赖的)。go mod tidy 会自动维护这个列表。

go.sum 文件

github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=

go.sum 记录每个依赖的加密哈希值,Go 每次下载依赖时会校验哈希是否匹配,防止依赖被篡改。不要手动修改 go.sum

版本管理

# 升级依赖到最新版本
go get -u github.com/google/uuid
 
# 安装指定版本
go get github.com/google/[email protected]
 
# 降级版本
go get github.com/google/[email protected]

Go 模块使用语义化版本(semver),格式为 vMAJOR.MINOR.PATCHgo get 会自动更新 go.modgo.sum

替换依赖

replace github.com/google/uuid => github.com/my-fork/uuid v1.6.1

replace 可以把一个依赖替换成另一个路径或本地路径,适合调试或临时修复。

replace github.com/google/uuid => ../local-uuid

用本地路径替换,适合开发阶段调试本地包。

清理依赖

go mod tidy

go mod tidy自动添加代码中用到但 go.mod 里没有的依赖,删除 go.mod 里有但代码中没引用的依赖。

供应商模式

go mod vendor

把所有依赖复制到项目的 vendor/ 目录下,编译时优先用 vendor/ 里的代码。适合需要离线构建锁定依赖源码的场景。

常见写法

命令说明
go mod init <path>初始化模块
go mod tidy整理依赖(增删)
go mod download下载依赖到缓存
go mod graph查看依赖关系图
go get <pkg>@<ver>安装/更新指定版本
go get -u <pkg>升级到最新版本
go mod vendor复制依赖到 vendor/
go mod verify校验依赖完整性

特点

  • go.mod 定义模块路径和依赖版本,是项目的依赖清单
  • go.sum 记录依赖的加密哈希,防止篡改
  • go mod tidy最常用的命令,自动维护依赖列表
  • 使用语义化版本(vMAJOR.MINOR.PATCH),大版本不同路径不同(v2 开始要加 /v2
  • go get 可以安装、更新、降级依赖
  • replace 用于临时替换依赖,调试或修复 bug
  • vendor/ 模式把依赖放进项目,适合离线构建
  • go.modgo.sum需要提交到版本控制

理解

模块就是给项目建了一张”购物清单”(go.mod)和”验货记录”(go.sum)。需要什么依赖写进去,Go 自动帮你下载和校验。go mod tidy 一键整理,不用手动管理版本号。有了模块,不同项目用不同版本的库也不会冲突。

引出

模块解决了依赖管理,但一个正经的 Go 项目除了代码文件,还有各种目录和配置。接下来看 Go 项目结构,学习 Go 社区推荐的标准项目布局。