
go.work 文件不是“自动联通”的开关,它只在你当前目录下被识别、且所有模块路径都正确相对时才生效;否则 go run 仍会报 missing module 或直接忽略本地修改。
go.work 必须放在共同父目录下,不能嵌套或错位
工作区根目录必须是所有要协同开发的模块的共同父目录。如果你把 go.work 放在 ./service/go.work 或家目录、空文件夹里,go 命令压根不会加载它。
- 正确做法:新建空文件夹(如
myworkspace),把./service、./client、./shared全部作为同级子目录放进去,再在myworkspace/下运行go work init - 常见错误:在
~/projects/myapp下执行go work init ./service,结果go.work生成了,但./client不在同级,后续go work use ./client会失败或被忽略 - go 不支持嵌套工作区:如果某个子目录下也存在
go.work,go会直接报错go: cannot use work file ... because a nested work file exists
go work use 只写路径,不改依赖,tidy 才是关键动作
go work use ./shared 只是把路径写进 go.work,它不修改任何 go.mod,也不刷新模块缓存。如果你的 ./service/go.mod 还写着 require example.com/shared v0.1.0,go build 依然会去拉远程版本。
- 必须立刻在主模块(比如
./service)目录下运行go mod tidy,它会自动删掉那行require,并把本地路径识别为“已提供” - 如果
tidy报错no required module provides package,说明./shared的module声明(如module example.com/shared)和./service中import的路径不一致,要统一 - 别在
go.mod里留replace行——工作区模式下它是冗余甚至冲突的,删掉所有replace
go run / go test 默认不走工作区,必须显式启用
你在 ./service 目录下执行 go run main.go,它完全无视 go.work,仍按单模块规则解析依赖。这是最容易踩的静默陷阱。
- 日常开发中,始终在工作区根目录(如
myworkspace/)执行go run ./service或go test ./shared/... - 如果必须在子目录操作,用
go run -workfile ../go.work ./main.go显式指定(注意路径是相对当前目录的) - 验证是否生效:在根目录运行
go list -m all,输出里出现example.com/shared v0.0.0-00010101000000-000000000000 => ./shared才算真正联通
VS Code 需手动重载 gopls,否则编辑器不认工作区
VS Code 里光有 go.work 不够,gopls 必须加载成功并识别到工作区,否则跳转、补全还是只认单个模块。
- 打开命令面板(Ctrl+Shift+P),运行
Go: Restart Language Server,强制重载 - 看 VS Code 窗口右下角状态栏:应显示类似
Workspace: service+shared (go1.21),而不是Module: service - 如果显示
Module,说明gopls没读到go.work——检查是否在myworkspace/根目录下打开整个文件夹(不是只打开./service子文件夹) -
.vscode/settings.json中无需额外配置,但确保没写"go.useLanguageServer": false
最常被忽略的是路径层级和命令执行位置:go.work 的路径是相对于它自身所在目录的,而 go run 是否启用工作区,只取决于你当前在哪执行、以及有没有显式指定 -workfile。哪怕 go.work 写对了,cd 错了目录,一切就归零。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











