go mod 要求每个module从大版本2开始,模块路径必须有类似 /v2
版本号的后缀,假如module example.com/mod
从 v1.0.0发展到v2.0.0,这时它的go.mod中的模块路径应该修改为 example.com/mod/v2
。go mod 认为如果一个module的两个不同版本之间引入路径相同,则它们必须是相互兼容的,而不同的大版本通常意味着是不兼容的,所以引入路径也不该相同,通过在模块路径上加上大版本后缀,这样就可以同时使用同一个模块的多个不同大版本。
对于 v0
和 v1
两个大版本,go mod不允许存在版本后缀,这是因为 v0
版本通常是不稳定版本,不提供兼容性保证,并且通常 v1
版本兼容最新的 v0
版本,所以从 v0
版本迭代到 v1
版本,不需要修改module 路径 。
作为特殊情况,以 gopkg.in
打头的module 不管是 v0
、v1
还是其他大版本都必须存在版本后缀,且它的的版本后缀是用 ‘.’ 而不是 ‘/’,比如:
对于一些比较老的项目可能当时go mod还没出现,但版本早已经迭代到v2
以上,或者有些项目没有遵循以上的原则,go mod为了能够正常使用它们,会在引入 v2
以上的版本后加上 +incompatible
以示提醒,比如 github.com/docker/docker
且这样的项目根目录下不允许存在 go.mod
文件,如果项目添加了go.mod
且又不遵循module path后缀原则,则将无法拉取到 v2
以上版本,如果手动指定v2
以上版本强制拉取则会报错:
对于那些比较老的go 模块,如果大版本已经达到 v2
以上,但不存在向后兼容问题,这时不建议添加 go.mod
文件,以便使用该模块的人能正常更新到最新版本,如果后续迭代出现大的变动已经无法向后兼容,这时应该升级一个大版本,并添加 go.mod
文件,同时模块path也要加上新的大版本后缀,使用者要使用该新版本则需要像引入一个新的模块一样使用带有后缀的module path。