$ go get golang.org/x/text
go: golang.org/x/text upgrade => v0.3.3
go: downloading golang.org/x/text v0.3.3
$
$ go list -m all
example.com/hello
golang.org/x/text v0.3.3
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e
rsc.io/quote v1.5.2
rsc.io/sampler v1.3.0
$ cat go.mod
module example.com/hello
go 1.15
require (
golang.org/x/text v0.3.3 // indirect
rsc.io/quote v1.5.2
)
$ cat go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
$ go get rsc.io/sampler
go: rsc.io/sampler upgrade => v1.99.99
go: downloading rsc.io/sampler v1.99.99
$ go test
--- FAIL: TestHello (0.00s)
hello_test.go:8: Hello() = "99 bottles of beer on the wall, 99 bottles of beer, ...", want "Hello, world."
FAIL
exit status 1
FAIL example.com/hello 0.014s
$
$ go list -m -versions rsc.io/sampler
rsc.io/sampler v1.0.0 v1.2.0 v1.2.1 v1.3.0 v1.3.1 v1.99.99
$ go get rsc.io/sampler@v1.3.1
$ cd $HOME/go/pkg/mod/rsc.io
$ ls
quote@v1.5.2 sampler@v1.3.0 sampler@v1.3.1 sampler@v1.99.99
$
Go 1.13及以后版本GO111MODULE=auto的行为变化。
GO111MODULE的默认值依然为auto。但无论repo是否在GOPATH,只要目录有go.mod,go编译器都会使用go module来管理依赖
如何创建模块
新建工作区和项目文件夹
init mod init $path
一是作为模块标识,二是作为模块的import path
此时会生成go.mod文件
当其他项目引用这个模块下的 package 时都会以该 import $path 作为共同的前缀
新建go文件
hello.go新建测试文件
hello_test.go,测试是否能正常调用Hello方法运行测试文件
如何添加依赖项
修改hello.go。用rsc.io/quote来实现Hello
再次运行测试。看来Hello()方法实现了国际化功能,需要修改一下测试用例。
测试通过了,证明Hello功能正常
此时会把直接依赖写到go.mod中
尝试列出目前的所有依赖。当前模块(主模块)始终是第一行,随后的才是真正的依赖关系
尝试列出所有的依赖关系。清晰明了,这个功能大赞
所有真正的依赖和哈希值会记录到go.sum中。哈希值的作用是确保所有依赖项不会被恶意修改。
如何更新依赖项。版本号最好带着语义信息,v0.1.2。主要版本是0,次要版本是1,补丁版本是2
尝试升级一下golang.org/x/text
执行go list -m all并且看看go.mod和go.sum情况。
golang.org/x/text已经升级到v0.3.3版本,go.mod也改成了
golang.org/x/text v0.3.3 // indirect。indirect表示该依赖不是由当前项目直接依赖,而是由其他依赖包间接依赖的。尝试升级rsc.io/sampler。发现版本太先进,兼容不了旧版本
尝试列出可用的版本以及挑选一个补丁版本。go get默认是获取@latest版本
此时。$GOPATH/pkg/mod/rsc.io存在rsc.io/sampler的多个版本
如何引用同一个依赖的不同主版本
修改hello.go。引用rsc.io/quote/v3
给测试文件添加以下行
再次测试一下
此时项目同时依赖rsc.io/quote和rsc.io/quote/v3
总结:
引用同一个依赖的不同版本毕竟不是什么好事。尝试将旧的api升级到新的api,然后将旧的依赖删除。
查看rsc.io/quote/v3版本有什么api。像是Hello升级到了HelloV3
修改hello.go,更换一下api
既然没有了多个版本,可以不用alias
重新运行test。一切正常
如何删除已下载但未引用的依赖。例如
rsc.io/quote利用tidy命令删除未使用的依赖项
重新测试