Golang Module学习使用

原文链接:http://www.chairis.cn/blog/article/101

介绍

美国当地时间2018年8月24日,Go 开发团队宣布推出 Go 1.11 正式版。

此版本增加了对被称作“模块(Go Modules)”的初步支持,这是 GOPATH 的替代方案,集成了对版本控制和软件包分发的支持。

自从Go 1.11 推出之后,一直也没有时间去学习新版本的特性,这次就来研究一下Go Modules的使用吧

1. go mod 命令

安装go 1.11版本后,可以通过以下命令大致看下go mod有哪些命令

go help mod

image.png

图中可以看到,go mod的命令语法为

go mod <command> [arguments]

  1. download: download modules to local cache (下载依赖的module到本地cache)
  2. edit: edit go.mod from tools or scripts (编辑go.mod文件)
  3. graph: print module requirement graph (打印模块依赖图)
  4. init: initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件)
  5. tidy: add missing and remove unused modules (增加丢失的module,去掉未用的module)
  6. vendor: make vendored copy of dependencies (将依赖复制到vendor下)
  7. verify: verify dependencies have expected content (校验依赖)
  8. why: explain why packages or modules are needed (解释为什么需要依赖)

2. go mod的使用

接下来将通过一个简单的项目介绍go mod的使用

2.1. 新建项目

首先创建一个空文件夹,用作项目目录

mkdir modtest

然后通过init命令初始化mod

cd modtest go mod init modtest

上述命令会在modtest目录下生成go.mod文件。

结果如下图所示
image.png

接下来,我们写一段简单的代码验证一下,在该目录创建main.go文件,写入以下代码:

package main import ( "fmt" ) func main() { fmt.Println("hello word") }

执行以下命令查看结果:

go run main.go

image.png

2.2. 添加github包

上一步成功创建了项目,接下来,我们要添加一个github的包,这里就简单的添加一个测试的包github.com/Chain-Zhang/modlib,这个是我自己做的一个及其简单的包,其中就只有一个方法,代码如下:

package modlib

func Message() string {
	return "this message from modlib"
}

这里打了个tag:v0.0.1

执行以下命令添加包到项目:

go get -m github.com/Chain-Zhang/modlib@v0.0.1

执行之后可以看下效果:
image.png

从图中可以看到,在go.mod文件中增加了一条内容:

module modtest require github.com/Chain-Zhang/modlib v0.0.1 // indirect

另外又多出一个文件go.sum

github.com/Chain-Zhang/modlib v0.0.1/go.mod h1:vQ6MFJ522Kt0KC6N5sati+nKWd685pu216mW0cW6EMw=

go.mod 则是描述直接依赖包

go.sum 则是描述依赖树锁定

之后我们在项目中调用一下我们modlib的方法试一下,代码如下:

package main import ( "fmt" "github.com/Chain-Zhang/modlib" ) func main() { msg := modlib.Message() fmt.Println(msg) }

执行以下命令,看下效果:

go run main.go // 输出:this message from modlib

2.2. 尝试下go mod命令

这个时候,我们可以尝试下gomod的几个命令

image.png

执行最后一个go mod vendor的时候,你会发现,在项目目录里面增加了个目录,vendor,而且,将所依赖的包也放进去了
image.png

2.3. go mod 翻墙

接下来,我们将modlib加入一段代码,该代码需引用golang.org/x/text:

package modlib import( "golang.org/x/text/language" "golang.org/x/text/message" "golang.org/x/text/number" ) func Message() string { return "this message from modlib" } func MaxIntegerDigits(){ const year = 1999 p := message.NewPrinter(language.English) p.Println("Year:", number.Decimal(year, number.MaxIntegerDigits(2))) }

并将打上v0.0.2的tag

然后在项目中调用MaxIntegerDigits方法:

package main import ( "fmt" "github.com/Chain-Zhang/modlib" ) func main() { msg := modlib.Message() fmt.Println(msg) modlib.MaxIntegerDigits() }

在执行以下命令更新包到v0.0.2:

go get github.com/Chain-Zhang/modlib@v0.0.2 // 错误: // go build golang.org/x/text/message: no Go files in // go build golang.org/x/text/number: no Go files in // go build golang.org/x/text/language: no Go files in

这是因为获取golang.org/x/...时需要翻墙,而我这里没有翻墙,不过没关系,设置下代理即可:

// bash mac export GOPROXY=https://goproxy.io

// powershell windows $env:GOPROXY = "https://goproxy.io"

然后再执行命令:

go get github.com/Chain-Zhang/modlib@v0.0.2
// go: finding golang.org/x/text/message latest
// go: finding golang.org/x/text/language latest
// go: finding golang.org/x/text/number latest

成功之后go.mod及go.sum的变化:

// go.mod
module modtest

require (
	github.com/Chain-Zhang/modlib v0.0.2
	golang.org/x/text v0.3.0 // indirect
)

// go.sum
github.com/Chain-Zhang/modlib v0.0.2 h1:Rj839yAnYX7yER2s28+92fDTkOTRqjr2AJIZ4vqTvRk=
github.com/Chain-Zhang/modlib v0.0.2/go.mod h1:vQ6MFJ522Kt0KC6N5sati+nKWd685pu216mW0cW6EMw=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

2.4. 版本回到v0.0.1

这个时候我们把版本再回到v0.0.1

go get github.com/Chain-Zhang/modlib@v0.0.1

这个时候因为我们调用了v0.0.2的modlib.MaxIntegerDigits方法,所以会报错,只要删掉就可以了。

但是在我们的go.mod中却有个多余的引用,即golang.org/x/text,因为v0.0.1中没有用到该包。

此时我们就可以执行go mod tidy来清除不必要的引用,和添加丢失的引用。执行之后,go.mod文件中对于golang.org/x/text的引用就不见了。

2.5. 其他

2.5.1. go get 命令

获取依赖的特定版本,用来升级和降级依赖。可以自动修改 go.mod文件,而且依赖的依赖版本号也可能会变。

与以前不同的是,新版 go get可以在末尾加 @符号,用来指定版本。
它要求仓库必须用 v1.2.0格式打 tag,像 v1.2
少个零都不行的,必须是语义化的、带 v前缀的版本号。

eg:

go get github.com/gorilla/mux # 匹配最新的一个 tag go get github.com/gorilla/mux@latest # 和上面一样 go get github.com/gorilla/mux@v1.6.2 # 匹配 v1.6.2 go get github.com/gorilla/mux@e3702bed2 # 匹配 v1.6.2 go get github.com/gorilla/mux@c856192 # 匹配 c85619274f5d go get github.com/gorilla/mux@master # 匹配 master 分支

2.5.2. go build 命令

  1. go build -mod=readonly 防止隐式修改 go.mod,如果遇到有隐式修改的情况会报错,可以用来测试 go.mod 中的依赖是否整洁,但如果明确调用了 go mod、go get 命令则依然会导致 go.mod 文件被修改。

  2. go build -mod=vendor 在开启模块支持的情况下,用这个可以退回到使用 vendor 的时代。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值