Go Modules的使用
source link: https://hkvision.cn/2019/08/01/go-modules%E7%9A%84%E4%BD%BF%E7%94%A8/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本文为原创文章,转载注明出处,欢迎关注网站https://hkvision.cn
自从go1.11
版本后,golang官方给出了一个管理第三方依赖的方式——Go Modules
,这是官方提倡的新的包管理机制。
go modules
的初始化
如果你使用的是golang-1.11的版本,你需要先将环境变量GO111MODULE
设置为on
,网上也有说法当当前目录里面有go.mod
文件的时候会自动开启(默认是auto
),由于笔者已经将版本升至1.12,没有尝试。
和传统的GOPATH
不一样,不要繁琐的src
,bin
等子目录,任何目录均可成为modules
(前提是不在GOPATH
里面),只要其中包含go.mod
文件。
那么如何包含go.mod
文件呢,你可以选择新建这个文件,然后在首行写上module {name}
即可,更好的做法是执行下面的命令
go mod init {name}
如果你的项目是从github
上clone
下来的,那么可以选择省略后面的name
,默认会使用git
管理的名字作为module name
初始化完成后会在目录下生成一个go.mod
文件
那么我们如何进行包管理呢,在有go.mod
的目录下,当我们执行go build
,go test
,go list
等命令的时候,go会自动帮我们更新依赖,并将依赖关系写入其中
我们会发现目录下多了一个go.sum
文件,看看里面是啥
是的,这个是我们引用的package
和其自身引用的版本记录。并且会记录下其所需的版本以及时间戳和hash值。
如果我们不做任何修改,默认会使用最新的包版本,如果包打过tag,那么就会使用最新的那个tag对应的版本。
如果你需要特定版本的包,可以在go.mod
里面修改require
来指定版本。你也可以通过命令修改
go mod edit -require="github.com/dgraph-io/[email protected]"
然后运行go mod tidy
,就会自动切换版本
下面我们来编译代码
go build -mod=readonly
这里的readonly
是指任何会导致依赖关系变动的情况都会编译失败
在启用Go Modules
之后,原先的GOPATH
就不再适用了。包括你使用go get
命令的时候,包不再被下载到GOPATH/src
目录下,而是被下载到缓存下(包括使用build
命令),这里的缓存是在GOPATH/pkg/mod
目录下(不知道这个目录能不能进行更换,否则仍然对GOPATH有一定的依赖,当然这个依赖不是很明显),这个目录和原先的src
目录结构类似,不同的地方在于,其每个module
有不同的版本,通过name@version
的方式对不同的包进行命名。
原先在GOPATH
时代,当需要下载墙外的包的时候(尤其是官方包golang.org/x/...
),我们需要先从github上下载,然后调整包的位置,相当麻烦(当然也可以设置git的代理,但是总觉得为了golang下载包就得设置git的代理,有点奇怪)。当有了Go Modules
,我们可以通过环境变量GOPROXY
设置代理,在下载包的时候走代理即可。
这里有一个开源的代理https://goproxy.io
依赖本地包
到目前为止,还有一个问题,即如果我们所依赖的包并没有发布在github
这种网站上,我们也不想发布上去,或者其本身就是一个子模块,那么应该怎么办。我搜索了很长时间的解决办法,最终找到这里
我们需要手动添加一下go.mod
require X v0.0.0
replace X v0.0.0 => "{local path to the X module}"
这里的replace
相当于对包进行重命名,在你不使用代理的时候,对于墙外的包可以用这种方式进行处理。
注意: 这里的
local path to the X module
一定要用绝对路径(我尝试过相对路径,不行)另外,在代码里面也不再需要
import ./X
,只需要import X
,因为你是从modules里面找包,而不是从本地找包
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK