Go Module需显式初始化、用go get或go mod tidy驱动依赖变更,禁手动修改go.mod/go.sum;项目须移出$GOPATH/src,模块名用域名格式,私有库需配GOPRIVATE。

Go module 不是“开了就能用”的开关,而是需要明确初始化、按规则写入依赖、靠命令驱动变更的一套约束性机制。直接在 go.mod 里手动增删行,或指望 go run 自动拉全依赖,大概率会遇到 cannot find package、version mismatch 或 CI 构建失败。
项目不在 $GOPATH/src 下才能启用 module 模式
Go 1.16+ 虽默认启用 module,但有个硬条件:当前目录不能位于 $GOPATH/src 内。否则 go build 仍走 GOPATH 模式,go.mod 文件会被完全忽略。
判断是否生效最简单的方式是运行:
go list -m
如果报错 no modules found,说明 module 模式根本没启动。
- 把项目移到
~/projects/myapp这类独立路径下(不要放在$GOPATH/src里) - 执行
go mod init example.com/myapp,模块名建议用可解析的域名或 GitHub 路径,别用myapp这种本地名 - 初始化后
go.mod是空的,不会自动分析代码里的import,也不会下载任何包
依赖不是“写进 go.mod 就完事”,得靠 go mod tidy 或 go build 触发下载
go mod init 只生成骨架,真正让依赖落地要靠两个动作之一:
- 运行
go build或go run main.go:Go 会扫描所有import,自动下载对应版本,并写入go.mod和go.sum - 或直接运行
go mod tidy:它会补全缺失的依赖、删掉未被引用的依赖,并同步更新go.sum
常见错误是 init 后立刻 go run 报 cannot find package——本质就是还没触发依赖下载。此时不要手动改 go.mod,更不要去 $GOPATH/src 手动放包。
升级、降级、替换依赖必须用 go get 或 go mod edit,别手改 go.mod
go.mod 是声明文件,不是配置文件。所有变更应由 Go 工具链生成,否则容易破坏 go.sum 校验或引发版本解析冲突。
- 升级单个包到指定版本:
go get github.com/sirupsen/logrus@v1.9.3 - 回退到旧版:
go get github.com/sirupsen/logrus@v1.8.0 - 临时替换为本地路径(仅开发调试):
go mod edit -replace github.com/you/lib=../lib,之后必须跟go mod tidy - 上线前必须删掉
replace行,CI 环境没有你的本地路径,构建必然失败
go get -u 会升级到最新兼容主版本(比如 v1.x → v1.y),但不会跨大版本(v1 → v2)。要升 v2,必须显式指定 @v2.0.0,且 import 路径需含 /v2 后缀。
go.sum 不是锁文件,但校验失败会直接中断构建
go.sum 记录每个模块的哈希值,作用是验证下载内容是否被篡改。它不锁定具体版本(那是 go.mod 干的事),但校验逻辑非常严格:
- 如果某依赖的 checksum 在
go.sum中存在,但实际下载内容不匹配,go build会直接报错退出 - 新增依赖时,
go mod tidy会自动追加 checksum;删除依赖时,它不会自动清理对应行,需手动删或重生成 - 多人协作中,
go.sum必须提交进 Git,否则不同人构建结果可能不一致
最容易被忽略的是:私有仓库依赖必须配 GOPRIVATE,否则 Go 会尝试走 proxy.golang.org 校验,导致拉取失败或校验不通过——这个环境变量一旦漏设,问题往往卡在 CI,而不是本地。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











