go clean -cache 清的是 $gocache 目录下已编译的中间产物(.a 文件),这些缓存用于加速构建,但源码或依赖变动时可能被错误复用,导致逻辑未更新;清理后首次构建变慢属正常现象。

go clean -cache 清的是什么,为什么改了代码不生效还怪它
它删的是 $GOCACHE 目录下已编译的中间产物(.a 文件),不是源码,也不是模块。这些文件让 go build 和 go test 跳过重复编译,但一旦源码、依赖或 Go 版本变动,旧缓存可能被错误复用。
常见错误现象:go build 速度突然变慢、改了函数逻辑却没触发重新编译、CI 构建结果和本地不一致。
- 执行前先确认路径:
go env GOCACHE(macOS 默认是$HOME/Library/Caches/go-build) -
go clean -cache不会清空整个目录,只删“过期”条目;要彻底清,得用:rm -rf $(go env GOCACHE)/*(注意末尾/*,别漏掉) - 如果设了
GOCACHE=off,这条命令什么也不会做 - 清理后首次构建明显变慢——这是正常表现,缓存重建需要时间
go clean -modcache 清的是模块源码,不是 GOPATH/src
它删的是 $GOMODCACHE(默认为 $GOPATH/pkg/mod)里的所有解压后的模块源码、.zip 包和校验数据。这个操作和你在 $GOPATH/src 下手动 git clone 的项目完全无关。
常见错误现象:cannot find module providing package xxx、checksum mismatch、go list -m all 显示的版本和 go.mod 对不上。
- 执行前务必确认
GO111MODULE=on,否则go clean -modcache静默无效 - 不要在发布前临时执行——清理后
go build会重新下载所有依赖,耗时不可控 - 只想删某个模块?手动删更安全:
rm -rf $GOMODCACHE/github.com/xxx@v1.2.3和$GOMODCACHE/cache/download/github.com/xxx - 清理后建议立刻跑
go mod verify,确保后续拉取的模块和go.sum一致
go clean -i 为什么有时候删不掉已安装的二进制
go clean -i 只清理「由当前目录下 main 包安装的二进制」。它不扫描整个 $GOBIN 或 $GOPATH/bin,也不跨目录生效。
比如你在 ~/proj/cmd/mytool 执行 go install,生成了 $GOBIN/mytool;然后 cd 到 ~/proj 再执行 go clean -i,它不会删 mytool——因为当前目录没有 main 包。
- 想确保删干净,
cd进每个cmd/xxx目录单独执行go clean -i - 若用
go install指定了-o输出路径,go clean -i无法识别该路径,必须手动rm - 它同时清理
$GOPATH/pkg中对应包的安装缓存(.a文件),但仅限于当前main包所依赖的子包
你自己写的 map / sync.Map 怎么清,别用 for range delete
运行时内存缓存(比如 map[string]interface{}、sync.Map、github.com/patrickmn/go-cache)不会被 go clean 命令触碰,必须在代码里显式处理。
用 map + sync.RWMutex:遍历时不能直接 delete(),应先收集 key,再单独删;或改用 for k := range m { delete(m, k) }(仅当无并发读写时安全)。
用 sync.Map:它不支持安全遍历+删除组合操作,得换回普通 map + sync.RWMutex,或者直接新建一个空实例赋值过去。
- 第三方缓存库如
go-cache通常自带Flush()方法,优先调用它 - 别在 HTTP handler 里对全局
map做for range delete,高并发下极易 panic - 清理时机比清理动作更重要:比如在服务 reload 阶段统一 flush,而不是靠定时器盲目扫
go clean 管不了你代码里 new 出来的 map,也管不了 IDE 后台静默构建产生的临时产物;它只负责工具链自己写的那几块磁盘区域。看清 go env 输出的实际路径,比背熟所有参数更关键。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











