一文详细了解 Go Module( 二 )


这样即可保持100%可重复构建 。当然您也可以手动升级D为最新可用版本或者指定其为其它版本 。
查看所选模块版本列表(包括间接依赖),可以使用:
go list -m all2.3 语义学版本引用
Go多年来推荐的包版本化方式:
开放使用的包在演进时应保持向后兼容的准则,Go 1兼容性准则即是一个好的参考 。不要移除已导出的名称,若要加一个新功能,需加一个新接口,不要改动老接口名 。实在需要推倒之前的,请创建一个新包,以新的路径而被引用 。
最后一句很重要,若破坏了兼容性,需更改包的引用路径 。
对Go 1.11模块而言,引用兼容性准则可以概述为:
若新包沿用旧包的引用路径,新包必须向后兼容旧包 。
参考语义学版本命名规则,当一个原始为v1或v1以上的包发生了不兼容变更,该包需要更改主版本 。
所以,根据引用兼容性准则及语义学版本命名规则(合称为语义学版本引用),主版本需要包含在引用路径内 。这样即可保障不兼容的主版本升级时,引用路径即会改变 。
根据语义学版本引用规则,选用Go Module的代码必须遵守如下规则:

  • a)语义学版本命名;
  • b)若一个Module的版本为v2及以上,模块的主版本必须包含在模块路径及引用路径中(例如,声明方:module github.com/my/mod/v2,引用方:require github.com/my/mod/v2 v2.0.0,包引用处:import "github.com/my/mod/v2/mypkg");
  • c)例外,若模块主版本为v0或v1,模块路径及引用路径无须包含主版本 。
通常来讲,引用路径不同的包是两个全然不同的包(如math/rand和crypto/rand是两个不同的包) 。同样,包含不同主版本的引用路径所标识的包亦是两个不同的包 。因此,example.com/my/mod/mypkg与example.com/my/mod/v2/mypkg是不同的包,且可能会在一次构建中同时引用 。
因有些模块还未转换为Module方式,过度期,会支持如下几个例外:
  • a)gopkg.in
  • 会继续支持gopkg.in/yaml.v1或gopkg.in/yaml.v2等引用方式 。
  • b)当引用还未Module化的v2+版本包时,会有'+incompatible'后缀 。
  • c)当Module模式未开启时,采用最小模块兼容性 。
即在Go 1.11邻近版本,不开启Module模式时(GO111MODULE=off),引用v2或以上版本,不会将版本加入路径中 。
3 使用3.1 模块支持激活
安装Go 1.11及以上版本,然后可以使用如下两种方式中的任一种激活模块支持 。
  • a)在$GOPATH/src文件夹之外使用go命令,且当前文件夹或其上层文件夹包含go.mod文件,而GO111MODULE环境变量未设置或设置为了auto;
  • b)设置GO111MODULE=on,然后调用go命令 。
即在$GOPATH/src之外使用模块支持,无需设置GO111MODULE环境变量,而在$GOPATH/src使用模块支持,需将GO111MODULE设置为on 。
3.2 定义一个模块
a)进入对应文件夹
$ cd path该文件夹可以为设置GO111MODULE=on的$GOPATH/src,或该文件夹之外的任意路径 。
b)执行go mod init
$ go mod init github.com/my/repo若在初始化一个v2+的模块,需要手动更改go.mod文件及.go代码,以在引用路径及模块路径加入版本信息(语义学版本引用) 。
c)构建模块
$ go build ./...“./...”模式匹配了当前模块下的所有包,go build将自动增加缺失的包 。
d)测试模块
$ go test ./...或者执行如下语句,可以运行模块内的测试及所有直接及间接依赖测试以检查不兼容问题 。
$ go test all3.3 依赖升降级
可以使用go get命令进行日常依赖升级及降级,其会自动更新go.mod文件,当然您也可以手动编辑go.mod文件 。
当然,go get也如go build,go test一样,会自动加入缺失的依赖包 。
查看可用的小版本或补丁更新,可以执行:
$ go list -u -m all将直接或间接依赖更新为最新的小版本或补丁版本,可以执行:
$ go get -u仅更新为补丁版本,可以执行:
$ go get -u=patchgo get foo等同于go get foo@latest,会将foo更新为最新版本 。
当有语义学版本时,最新版本为语义学最新版本,没有时,为最新的提交 。
一个通常错误的认为是,go get -u foo仅获取最新版本的foo 。其实其还会获取foo的直接或间接依赖的最新版本 。
更新版本,推荐的做法是先运行go get foo,好使时再运行go get -u foo 。
进行版本升降级时,可以使用@version后缀,如:
$ go get foo@v1.6.2或
$ go get foo@e3702bed2还支持模块查询,如:


推荐阅读