这个实验用代码和隔离缓存观察go run、go build、go get、go mod download、go mod tidy分别做了什么。实验在.lab中创建嵌套模块, 不会修改仓库根目录的go.mod和go.sum。
先记住结论
go run和go build会按需下载模块文件已经完整记录、但本地缓存缺失的依赖。源码新增一个第三方
import,而go.mod还没有对应模块时,通常要先执行go get 包路径(或者明确使用允许修改模块文件的模式)。go get的重点是选择依赖版本并修改go.mod;为了完成版本解析,它也会下载。go mod download的重点是把确定版本的模块放进本地缓存;它不会根据源码判断 哪个import应该新增到go.mod。go mod tidy的重点是让源码、go.mod、go.sum对齐。它会加入缺失的必要依赖, 删除不再提供相关包的依赖,并清理校验和。tidy删除的是模块文件中的依赖记录,不会删除$GOMODCACHE中已经下载的源码。
三种状态对照
1. 源码已经import,但go.mod没有记录
命令 | 结果 |
|---|---|
| 默认报错,提示使用 |
| 解析版本、写入 |
| 无参数时不会从 |
| 扫描源码,添加缺少的必要模块和校验记录,并按需下载。 |
2. 源码没有import,但go.mod写了模块
命令 | 结果 |
|---|---|
| 不会删除该记录;由于代码不需要其包,通常不下载完整源码,但可能按模块图需要读取元数据。 |
| 保留、添加或调整指定版本并下载; |
| Go 1.17 及以后,无参数时会下载主模块明确 |
| 如果它对源码、测试、工具和依赖图确实都不相关,就从 |
3. 源码有import,go.mod/go.sum记录完整,但缓存为空
命令 | 结果 |
|---|---|
| 按需自动下载,然后运行或构建。 |
| 下载,并可能按参数重新选择版本;没有版本后缀时可能升级到最新版。 |
| 下载已确定版本到缓存,不编译、不运行。 |
| 为分析包图而下载,保留必要依赖,并整理直接/间接标记和校验记录。 |
如果只是手写了go.mod,但还没有对应的go.sum条目,当前 Go 默认可能以missing go.sum entry拒绝run/build。可使用go get、go mod tidy或go mod download建立校验记录;显式使用-mod=mod也允许构建命令修正模块文件。
建议,先tidy再run