golang module 使用教程
Go module 是golang最新的包管理工具,可以使依赖包版本信息更明确与可控。module 是关于Go packages的集合,存储在根目录下的go.mod文件中,go.mod 定义了模块的模块路径以及模块的依赖属性,依赖属性包含模块路径以及特定寓意的版本信息。
需要注意的是:在Go 1.13之前go module 在GOPATH下是默认不开启的,这是为了兼容的需要,如果需要使用go module可以在GOPATH/src外的路径创建go.mod文件。
本文会介绍Go module的一些基本用法;
- 常见命令
- 创建一个模块
- 添加一个依赖
- 升级依赖
- 其他命令
常见命令
go mod 提供了以下命令
- download: 下载依赖包到本地缓存 ($GOPATH/pkg/mod), 该目录下的包所有项目共享;
- edit : 编辑go.mod;
- graph: 打印模块的依赖图;
- init: 在当前目录初始化mod;
- tidy : 添加缺失的依赖包并清理没有使用的包;
- vendor : 将依赖包复制到vendor目录;
- verify: 验证依赖是否正确;
- why : 解释为什么需要这个依赖;
创建一个模块
如前文所说在GOPATH外的创建一个目录,例如 ~/gomod/hello;
执行一下子命令
1 ~/gomod/hello$ go mod init example.com/hello
2go: creating new go.mod: module example.com/hello
创建hello.go
1package hello
2
3func Hello()string {
4 return "Hello, world."
5}
为使用SayHi,创建test文件 hello_test.go
1package hello
2
3import "testing"
4
5func TestHello(t *testing.T) {
6 want := "Hello, world."
7 if got := Hello(); got != want {
8 t.Errorf("Hello() = %s, want %s", got, want)
9 }
10}
执行测试用例
1 ~/gomod/hello$ go test -run TestHello
2PASS
3ok example.com/hello 0.006s
添加一个依赖
1package hello
2
3import "rsc.io/quote"
4func Hello()string {
5 return quote.Hello()
6}
执行
1go: extracting rsc.io/quote v1.5.2
2go: extracting rsc.io/sampler v1.3.0
3PASS
4ok example.com/hello 0.009s
此时会将代码下载到$GOPATH/pkg/mod目录下,之后运行不会重复下载,可以到go.mod已经更新了
1module example.com/hello
2
3go 1.12
4
5require rsc.io/quote v1.5.2
使用 go list -m all 可以查看所有依赖
1$ go list -m all
2example.com/hello
3golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
4rsc.io/quote v1.5.2
5rsc.io/sampler v1.3.0
此时目录下多了一个go.sum文件,这个文件是做什么的呢?
1golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
2golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
3rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
4rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
5rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
6rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
可以看出该文件存储了包的路径 版本 还有校验值;每次执行命令时都会check 该校验是否与download目录下的是否一致;不一致就会报错
1verifying rsc.io/quote@v1.5.2/go.mod: checksum mismatch
2 downloaded: h1:Q15uSTpOVzCmer7yFUWKviBR7qLGLuYQ5zPmjACcaxQ=
3 go.sum: h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
升级依赖
加入要把quote包升级到其他版本,比如v3(需要提前知道升级的版本以及其中函数),
1package hello
2
3import (
4 quoteV3 "rsc.io/quote/v3"
5)
6func Hello()string {
7 return quoteV3.HelloV3()
8}
运行 go test, 会自动下载V3
1go test
2go: downloading rsc.io/quote/v3 v3.1.0
3go: extracting rsc.io/quote/v3 v3.1.0
4PASS
5ok example.com/hello 0.008s
查看 go.mod
1module example.com/hello
2
3go 1.12
4
5require (
6 golang.org/x/text v0.3.2 // indirect
7 rsc.io/quote v1.5.2
8 rsc.io/quote/v3 v3.1.0
9)
并没有删除 rsc.io/quote v1.5.2 ,这需要执行 go mod tidy 来去除不使用的包。
1$ go mod tidy
2$ cat go.mod
3module example.com/hello
4
5go 1.12
6
7require (
8 golang.org/x/text v0.3.2 // indirect
9 rsc.io/quote/v3 v3.1.0
10)
其他命令
- replace 替换依赖项模块: 可以将包替换成另一个包或者不同版本;
- exclude 忽略依赖项模块;
总结
- go mod init 创建一个模块,并创建文件go.mod;
- go build , go test 还有其他关于编译的命令都会按需将依赖添加到go.mod;
- go list -m all 输出当前模块所有的依赖;
- go mod tidy 可以删除不使用的依赖;