go模块下载后存于$gopath/pkg/mod(即gomodcache),其中cache/download存.zip/.mod/.info等原始文件,解压后源码存于@v/伪版本目录并由符号链接指向;$gocache专用于编译中间文件缓存,与模块源码缓存无关。

Go模块下载后存哪儿?go env GOPATH和go env GOCACHE到底管什么
Go模块不存进GOPATH/src,而是统一放在GOCACHE下的pkg/mod目录里——这是1.11启用模块模式后的硬性变更。你执行go get或go build时,所有模块都会被解压、校验、缓存到$GOCACHE/pkg/mod,而GOPATH只影响旧式GOPATH模式的构建逻辑,对模块依赖无实际作用。
验证方式很简单:go env GOCACHE查路径,然后进pkg/mod看结构。你会看到:cache/download存原始zip/tar.gz包和checksum文件,cache/download/<module>/@v/</module>下有list、v1.2.3.info、v1.2.3.mod、v1.2.3.zip四类文件;而cache/download/<module>/@v/v1.2.3.zip</module>解压后的内容,最终被软链接到cache/download/<module>/@v/v1.2.3</module>(注意:不是直接放源码,而是放解压后带完整路径的副本)。
-
go env -w GOCACHE=/tmp/gocache可临时改缓存位置,适合调试或隔离测试 - 删除
pkg/mod不会丢checksum数据——它们在cache/download里独立保存,重装时能快速验证 - 别手动删
pkg/mod/cache子目录,容易破坏go mod download的原子性校验
go mod download到底做了哪几件事?从网络请求到本地落地的完整链路
它不是简单“下载zip”,而是一套带校验、分层缓存、符号链接的三阶段操作:先查cache/download有没有已知版本的.info和.mod,再根据.info里的Version和Sum去比对远程/@v/list和/@v/v1.2.3.info,确认无误后才下载v1.2.3.zip并校验SHA256,最后解压到cache/download/<module>/@v/v1.2.3</module>,并创建指向它的软链接cache/download/<module>/@v/v1.2.3.zip</module> → v1.2.3。
- 失败常见于
checksum mismatch错误,本质是本地.mod文件记录的sum和远程不一致,通常因代理篡改或私有仓库未同步go.sum -
go mod download -json可输出每一步的URL、size、sum,适合排查卡在哪一环 - 如果模块用
replace指向本地路径,go mod download会跳过网络请求,但依然会在pkg/mod里建软链接指向本地目录
为什么pkg/mod里一堆@v、@latest、@master目录?它们怎么共存又互不干扰
@v是语义化版本的真实存储区,@latest和@master只是指向@v某版本的符号链接,不是独立副本。比如github.com/gorilla/mux@latest可能软链到github.com/gorilla/mux@v1.8.0,而@master若存在,则指向github.com/gorilla/mux@v0.0.0-20230101000000-abcdef123456这种伪版本。
-
go list -m -f '{{.Dir}}' github.com/gorilla/mux@latest能查出它实际解析到哪个@v路径 - 伪版本(如
v0.0.0-yyyymmddhhmmss-commit)由Go自动生成,用于commit-hash引用,其.info文件里记录了真实commit和时间戳 - 不同项目即使引用同一模块的不同版本(如
v1.7.0和v1.8.0),在pkg/mod里也是独立目录,靠路径隔离,不共享文件
想清理又怕崩?哪些目录能删、哪些删了要重下、哪些根本删不掉
pkg/mod/cache可以安全清空——它只是download过程中的临时解压区,删了不影响已缓存的模块;pkg/mod/download才是核心,删了就得重下所有模块的zip和校验文件;而pkg/mod/<module>/@v/</module>下的具体版本目录(如v1.2.3)是硬链接或解压结果,删了会导致go build报cannot find module,必须go mod download重建。
-
go clean -modcache等价于删整个pkg/mod,但它会保留go.sum和go.mod,重build时自动补全 -
go mod verify只检查go.sum和本地模块内容是否匹配,不触发下载,适合CI中做完整性断言 - 私有模块若用
replace或go mod edit -replace,其路径不在pkg/mod里,删缓存不影响它们——但go mod vendor会把它们复制进去
真正麻烦的是checksum校验链:一旦download/<module>/@v/v1.2.3.mod</module>被改写或损坏,后续所有依赖该模块的构建都会失败,且Go不会自动修复,只能删对应@v目录再重下——这个细节常被忽略,直到CI流水线突然卡住才意识到。











