![一文详细了解 Go Module](http://img.jiangsulong.com/220405/0451232633-0.jpg)
文章插图
1 速览在正式了解Golang Modules之前,我们先速览一下其使用方式 。
在$GOPATH之外的任意地方,创建一个文件夹:
$ mkdir -p /tmp/hello$ cd /tmp/hello然后初始化一个新的Module:
$ go mod init github.com/olzhy/hello输出:
go: creating new go.mod: module github.com/olzhy/hellogo.mod内容为:
module github.com/olzhy/hellogo 1.12然后写一段代码:
$ cat < hello.gopackage mainimport ( "fmt" "github.com/olzhy/quote")func main() { fmt.Println(quote.Hello())}EOFbuild一下:
$ go buildgo: finding github.com/olzhy/quote latestgo: downloading github.com/olzhy/quote v0.0.0-20190510033103-5cb7d4598cfago: extracting github.com/olzhy/quote v0.0.0-20190510033103-5cb7d4598cfago.mod内容为:
module github.com/olzhy/hellogo 1.12require github.com/olzhy/quote v0.0.0-20190510033103-5cb7d4598cfa可以看到,其会从https://github.com/olzhy/quote master分支拉取最新提交5cb7d4598cfa 。
该依赖工程非Module管理模式,其仅有两个文件:
hello.goREADME.md现在给依赖工程打一个TAG,名为v1.0.0 。
然后hello工程更新依赖:
$ go get -ugo: finding github.com/olzhy/quote v1.0.0go: downloading github.com/olzhy/quote v1.0.0go: extracting github.com/olzhy/quote v1.0.0查看go.mod内容为:
module github.com/olzhy/hellogo 1.12require github.com/olzhy/quote v1.0.0如下为使用Golang Module后的日常工作流 。
每日工作流:
- a)源码根据需要加入包引入语句;
- b)标准命令,如go build及go test等会自动更新go.mod并下载依赖包;
- c)当需要特定版本时,可以使用诸如go get foo@v1.2.3,go get foo@master,go get foo@e3702bed2命令或直接编辑go.mod文件 。
- a)go list -m all 查看一次构建使用的直接及间接依赖的最终版本;
- b)go list -u -m all 查看直接及间接依赖的可用的小版本或补丁版本更新;
- c)go get -u 或 go get -u=patch 将直接与间接依赖更新为最新小版本或补丁版本;
- d)go build ./... 或 go test ./... 构建或测试模块中的所有包;
- e)go mod tidy 从go.mod清理不再使用的包;
- f)go mod edit -replace foo@v1.2=../foo 替换依赖为本地复制或指定版本;
- g)go mod vendor 转换为vendor依赖方式 。
Module是一组相关Go package的集合,其作为一个单独的单元来版本化 。
Module记录精确的依赖项,提供可重复的构建 。
通常,一个版本控制仓库仅包含一个Module(支持单仓库多Module,但其会比单仓库单Module复杂很多) 。
仓库、模块与包的关系:
- a)一个仓库包含一个或多个模块;
- b)一个模块包含一个或多个包;
- c)一个包在一个文件夹包含一个或多个.go文件 。
模块由一组源文件树在根目录定义一个go.mod文件,模块源码可以位于GOPATH之外,有如下原语module,require,replace,exclude 。
如下为github.com/olzhy/hello模块的go.mod文件示例内容:
module github.com/olzhy/hellorequire ( github.com/some/dependency v1.2.3 github.com/another/dependency/v4 v4.0.0)可以看到,一个模块通过module原语声明模块ID,其标识模块路径 。该模块下某一个包的被引用路径由该模块路径与自go.mod所在路径起一直到包的路径止的相对路径共同决定 。
如,一个模块在go.mod声明其ID为example.com/my/module,那么引用该模块下mypkg包的代码为:
import "example.com/my/module/mypkg"2.2 版本选择
若源码中增加了go.mod中未require的新的依赖包,绝大多数诸如go build,go test命令会自动找到对应的包并在go.mod中采用require原语加入该直接依赖的最高版本 。
例如,您依赖的模块M的带标签的发布版本为v1.2.3,那么您的go.mod会新加入require M v1.2.3这一行语句,意味着依赖模块M所允许的版本>= v1.2.3并< v2(v2被认为与v1不兼容) 。 最小版本选择算法用于对一次构建的所有模块选择版本,对于每个模块,采用该算法选择的版本为语义学最高版本 。
下面举个例子:
若您依赖的模块A依赖D(require D v1.0.0),而您依赖的模块B同样依赖D(require D v1.1.1),然后,最小版本选择(选择最高的版本)将会选择v1.1.1版本的D 。而选择v1.1.1版本的D是一致的,即使将来发布了v1.2.0版本的D 。
推荐阅读
- 机器学习算法中的7个损失函数的详细指南
- 一文讲清楚抖音电商“FACT经营矩阵”模型
- 新增功耗 买新手机,在处理器上你需要了解的方面
- 老人咳嗽有痰吃什么好的快,饮食需了解
- 带你了解分布式架构的前世今生
- 这篇文章把 Linux 系统讲的如此详细,看完你一定会有质的飞跃
- 新型降血糖口服药物——DPP-4抑制剂,你了解多少
- 加碘盐,您了解吗?
- 忽悠了我们十几年的白酒骗局,以及高端酒“猫腻”,你都了解吗?
- 汽车故障灯你认识几个?为了行车安全,这些有必要了解