学完这篇,你能独立完成 Go 项目的依赖初始化、增删、升级与排错,遇到 missing go.sum entry、checksum mismatch 这类报错不再抓瞎。
Go 1.16 之后 Modules 已是默认模式,GOPATH 那套基本可以忘掉了。下面按项目从 0 到 1 的顺序讲。
第一步:初始化模块
在项目根目录执行:
go mod init github.com/yourname/yourrepo
这会生成一个 go.mod。文件名里的 module path 不是随便起的,它决定了别人怎么 import 你。
注意:如果这个模块会被别人引用(开源库、公司内部公共库),module path 必须和真实仓库地址一致,否则别人 go get 时会报 module declares its path as X but was required as Y。纯业务项目随便起也可以,但建议保持一致的规范。
第二步:日常增删依赖
三种方式,按场景选:
go get github.com/gin-gonic/gin@v1.9.1
# 2. 装最新版
go get github.com/gin-gonic/gin@latest
# 3. 代码里先写 import,再让 go 自己补
go mod tidy
go mod tidy 是最该养成习惯的命令:它会删掉没用的依赖、补上缺的依赖、同步 go.sum。提交代码前跑一次,基本不会出错。
想查为什么某个依赖被引入:
go mod why -m github.com/some/module
go mod graph | grep some/module
注意:go.mod 里带 // indirect 标记的,是间接依赖(你没有直接 import,但是别的包需要它)。别手动删,删了 go mod tidy 会加回来。
第三步:理解 go.mod 和 go.sum 的分工
go.mod:声明依赖和版本,是"意向书"
go.sum:记录每个模块的哈希校验值,是"防篡改凭证"
两个文件都要提交到 Git。
Go 采用 最小版本选择(MVS):当 A 要 v1.2、B 要 v1.5 时,最终选 v1.5,而不是最新版。这保证了构建可复现。想整体升级:
go get -u ./... # 升级到兼容的最新小版本
go get -u=patch ./... # 只升级补丁版本,最保守
注意:主版本号(v1 → v2)在 Go 里属于"不同的模块"。要用 v2 必须改 import 路径为 github.com/x/y/v2,模块自己的 go.mod 里 module 名也得带 /v2。这是强制规则,不是建议。
第四步:配置代理和私有仓库
国内直连 proxy.golang.org 基本不通,先设代理:
go env -w GOPROXY=https://goproxy.cn,direct
go env -w GOSUMDB=sum.golang.google.cn
要拉公司内网的 Git 仓库时,必须让 Go 绕过公共代理和校验:
go env -w GOPRIVATE=git.mycompany.com,github.com/myorg/*
GOPRIVATE 会自动让这些路径跳过代理和 sumdb。如果内网 Git 是 http 而非 https,再加 GOINSECURE=git.mycompany.com。
注意:GOPRIVATE 是前缀匹配。写 github.com/myorg 会把该组织下所有仓库都算私有,别写成 github.com。
第五步:常见报错怎么修
missing go.sum entry
说明 go.sum 和 go.mod 不同步,执行 go mod tidy 或 go mod download 即可。
checksum mismatch
通常是有人强推了 tag 或缓存脏了。清缓存再拉:
go clean -modcache
go mod download
拉私有库报 403 / unknown revision
先确认 GOPRIVATE 设了,再确认本机 Git 有权限(SSH key 或凭据配置好)。可以用 git ls-remote https://... 单独验证。
依赖版本永远升不上去
检查是不是被 replace 锁死了。replace 常用于本地联调:
replace example.com/lib => ../lib
联调完记得删掉,否则 CI 上会因为找不到本地路径而失败。
第六步:两种进阶用法
vendor 模式:把所有依赖拷进项目内的 vendor/ 目录,构建时不联网。
go mod vendor
go build -mod=vendor
适合内网离线构建,缺点是仓库体积变大、升级时要记得重新 go mod vendor。
多模块工作区:同时开发几个互相依赖的模块时用 go.work:
go work init ./service ./common
go work use ./service ./common
go.work 一般只留在本地,不要提交(除非团队约定)。
注意:Go 1.18 引入了工作区,但 CI 环境如果不支持或没配好,go.work 会造成"本地能编、CI 不能编"。生产构建建议固定用 go.mod,工作区只当本地加速手段。
小结
go mod init 的 module path 要规范,能被引用的模块必须和仓库地址一致。
- 提交前跑
go mod tidy,go.mod 和 go.sum 都要进版本库。
- 理解 MVS:Go 选的是"能满足所有依赖的最小版本",不是最新版。
- v2 以上主版本必须改 import 路径,这是硬规则。
- 国内必设
GOPROXY、GOSUMDB,私有库必设 GOPRIVATE。
- 报错优先试
go clean -modcache + go mod download。
replace 用于临时联调,vendor 用于离线构建,go.work 用于本地多模块——三者都别混进生产流程。