Go要求v2及以上主版本必须在模块路径中添加/v2后缀,如example.com/pkg/v2,以区分独立模块并避免导入冲突;/vN中的N只能是纯数字,不能为/v2.0等格式。

主版本号变更必须改模块路径
Go 不允许 example.com/pkg 同时引入 v1.5.0 和 v2.0.0 —— 工具链会报错:ambiguous import: found example.com/pkg in multiple modules。这不是配置问题,而是设计强制约束。
正确做法是:发布 v2 时,同步把模块路径改成 example.com/pkg/v2,并在其 go.mod 第一行写明:module example.com/pkg/v2。这样 v1 和 v2 就是两个完全独立的模块,可共存于同一项目。
- v0.x.y 和 v1.x.y 不需要路径后缀,
import "example.com/pkg"即可 - v2 及以上必须带
/v2,导入语句也得同步改成import "example.com/pkg/v2" - 路径后缀不是可选修饰,而是 Go 解析器识别主版本的唯一依据
为什么 v2 必须加 /v2 而不是 /v2.0 或 /v2.1
Go 只认 /vN(N 为纯数字)这种形式的主版本后缀。写成 /v2.0 或 /v2.1 会导致 go build 失败,报错类似:cannot find module providing package example.com/pkg/v2.0。
这是因为模块路径中的后缀只表示主版本号,不参与语义化版本比较;次版本和修订号由 tag 决定,与路径无关。
立即学习“go语言免费学习笔记(深入)”;
-
module example.com/pkg/v2对应所有 v2.x.y 版本 - 该模块下打的 tag 必须是
v2.0.0、v2.1.3、v2.5.0-beta.1等,不能是v2.0或v2 - 如果误用
/v2.0,go list -m -versions会完全找不到该模块的任何版本
v0 和 v1 的主版本号特殊处理
v0.x.y 被视为不稳定开发阶段,v1.x.y 是首个稳定主版本,二者都不强制要求路径后缀。但这也意味着:v0 到 v1 的升级不触发路径变更,工具链默认认为它们是兼容演进——实际未必。
所以如果你在 v0 阶段就公开了 API,又想保留未来 v1 的兼容承诺,建议从一开始就按 v1 发布,避免用户依赖上不稳定的 v0 接口。
- v0.1.0 → v0.2.0 可能含破坏性变更,无需路径变动
- v0.9.0 → v1.0.0 也不强制改路径,但强烈建议改:提前建立稳定预期
- 一旦用了
v1路径,后续所有 v1.x.y 都必须保持向后兼容
伪版本里主版本号怎么算
伪版本(如 v0.0.0-20240512183022-abcdef123456)不体现主版本号逻辑,它只是时间戳 + commit hash 的编码。Go 工具链根据其前缀(v0.0.0-)推断它属于 v0 主线,因此不会触发 /vN 路径检查。
但它仍受主版本路径约束:如果你的模块路径是 example.com/pkg/v2,那所有伪版本都必须出现在该路径下,且对应代码只能引用 v2 兼容的 API。
- 伪版本只用于未打 tag 的开发分支,生产环境应避免长期依赖
-
go get example.com/pkg@abcdef123456生成的伪版本,会自动归入该模块当前主版本路径 - 若模块路径是
/v2,则伪版本也属 v2 系列,即使它实际基于 v1 分支修改而来


















