go.work必须置于工作区根目录且不支持嵌套;所有模块需平级,replace须用./开头的相对路径;go run/test需在根目录执行或显式指定-workfile;ide需手动重载。

go.work 文件必须放在工作区根目录,且不能嵌套
Go 1.18 引入的 go.work 是多模块协同开发的唯一官方机制,但它不支持“子工作区”——一旦某个子目录下也放了 go.work,go 命令会直接报错 go: cannot use work file ... because a nested work file exists。这意味着你不能在项目 A 的子模块里再建一个工作区。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 所有参与协同的模块(比如
./api、./core、./cli)必须是平级子目录,共同位于同一个go.work所在根目录下 -
go.work文件本身应放在最外层目录,例如~/myproject/go.work,而不是~/myproject/api/go.work - 用
go work init初始化后,立刻用go work use ./api ./core ./cli显式添加路径,避免依赖隐式发现(它只扫描当前目录下的go.mod,不可靠)
replace 指向本地模块时,路径必须是相对路径且以 ./ 开头
很多人写 replace example.com/core => /home/user/myproject/core,结果 go build 报错 replace directive must not be absolute。Go 要求 go.work 中的 replace 必须用相对路径,否则拒绝加载。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 正确写法只有
replace example.com/core => ./core,路径相对于go.work文件所在位置 - 如果模块不在工作区根目录下(比如在
../shared/core),先软链进来或调整结构——go.work不支持跨父目录引用 - 注意:这里的
replace是全局生效的,会影响所有被use的模块,不是单个go.mod的局部替换
go run 和 go test 默认不识别工作区,需显式启用
你在 ./api 目录下执行 go run main.go,它依然会按老方式解析依赖,完全无视 go.work ——除非你加 -workfile 或把命令移到工作区根目录运行。这是最容易踩的静默陷阱。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 日常开发中,始终在工作区根目录执行
go run ./api或go test ./core/...,而不是 cd 进子模块再跑 - 如果必须在子目录操作,用
go run -workfile ../go.work ./main.go显式指定(注意路径是相对当前目录的) -
go list -m all是验证当前是否在工作区模式下的最快方式:输出里出现example.com/core v0.0.0-00010101000000-000000000000 => ./core才算生效
IDE(如 VS Code + Go extension)需要手动触发工作区重载
VS Code 不会自动感知 go.work 变更。你加了新模块、改了 replace,编辑器里的跳转、补全、诊断可能还是旧状态,甚至提示 cannot find package。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
- 修改
go.work后,在 VS Code 命令面板(Ctrl+Shift+P)运行Go: Restart Language Server - 确保设置里
"go.useLanguageServer": true,且没有启用过时的gopls配置项如"go.gopath" - 检查右下角状态栏是否有
Go (work)标识;没有的话,点击它并选择 “Select Go Workspace”,手动指向go.work文件
go.work 就万事大吉,却忽略了路径相对性、命令执行位置和 IDE 缓存这三个硬约束。










