GO111MODULE=on时GOPATH完全不参与依赖解析,所有依赖均来自$GOPATH/pkg/mod缓存;但GOPATH仍必须存在,因go install工具需写入$GOPATH/bin且模块缓存路径依赖它。

GO111MODULE=on 时 GOPATH 完全不参与依赖解析
只要 GO111MODULE=on(推荐永久设置),go build、go run、go test 等命令就彻底忽略 $GOPATH/src,也不从那里读取任何依赖源码。所有依赖都来自 $GOPATH/pkg/mod 缓存目录,路径形如 github.com/gin-gonic/gin@v1.9.1。
常见错误现象:import "github.com/some/pkg" 报错 “cannot find module providing package”,但你明明在 $GOPATH/src/github.com/some/pkg 下放了代码 —— 这是因为 Go Modules 模式下,它根本不看那个目录。
- 不是“优先查 GOPATH,找不到再查 mod 缓存”,而是直接跳过 GOPATH
-
go get命令此时只更新go.mod和下载到$GOPATH/pkg/mod,不再碰$GOPATH/src -
go list -m all显示的全是@vX.Y.Z格式,绝不会出现裸路径(如github.com/some/pkg)
GOPATH/bin 仍是全局工具的唯一落点
即使全面启用 Go Modules,go install 安装的可执行工具(比如 gopls、stringer、swagger)仍固定写入 $GOPATH/bin,且必须把该路径加入 $PATH 才能全局调用。
容易踩的坑:go install github.com/swaggo/swag/cmd/swag@latest 成功后,运行 swag 却提示 command not found —— 很可能只是漏加 $GOPATH/bin 到环境变量。
立即学习“go语言免费学习笔记(深入)”;
- 多个 GOPATH 路径(如
export GOPATH="/a:/b")时,go install总写入第一个路径的bin/ -
$GOPATH可以是任意路径,但bin子目录名不可改;Go 工具链硬编码识别它 -
go install不受go.mod影响,哪怕当前目录没有go.mod,它也照常安装到$GOPATH/bin
go mod init 的模块路径和 GOPATH 无关
go mod init github.com/yourname/project 中的路径只是逻辑标识符,不是文件系统路径。你完全可以把项目放在 /tmp/myapp 或 ~/Desktop/xyz,只要 go.mod 里声明了模块路径,Go 就认这个路径为模块根。
新手常误以为:模块路径必须匹配 $GOPATH/src 下的子目录结构。这是 GOPATH 时代的遗留思维,Go Modules 下完全无效。
- 模块路径可以是私有域名(
git.internal.company/project)、假域名(example.com/foo),甚至纯本地路径(myproject,但不推荐) - 如果模块路径含
.git或其他 VCS 后缀,go get会尝试按该地址拉取 —— 与 GOPATH 完全无关 - 模块路径一旦写入
go.mod,后续所有import都需严格匹配,大小写、斜杠都不能错
go.sum 文件校验的是模块缓存,不是 GOPATH
go.sum 记录的是每个依赖模块的 module path + version 对应的哈希值,校验目标是 $GOPATH/pkg/mod 下对应版本的解压后内容(即 cache/download/... 里的 zip 解包结果),而非 $GOPATH/src 里的任何东西。
这意味着:即使你手动修改了 $GOPATH/src 下某个库的代码,只要没动 go.sum 且没触发 go mod download,构建时依然用缓存里的原始版本 —— $GOPATH/src 在 Go Modules 下已成“幽灵目录”。
-
go mod verify只检查$GOPATH/pkg/mod缓存是否被篡改,不检查$GOPATH/src - 清空
$GOPATH/src对 Go Modules 项目毫无影响;清空$GOPATH/pkg/mod则会导致下次构建重新下载 -
go mod download -json输出的路径全是缓存路径,例如/home/user/go/pkg/mod/cache/download/github.com/xxx/@v/v1.2.3.zip
GOPATH 作为环境变量仍然必须存在且有效**——不是为了存放项目或依赖,而是为了让 go install 知道往哪写二进制,也让 go 命令能找到自己的模块缓存根目录 $GOPATH/pkg/mod。删掉 GOPATH 或设为空,go mod 命令会直接报错。


















