1

Go Modules的使用

 2 years ago
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.
neoserver,ios ssh client

本文为原创文章,转载注明出处,欢迎关注网站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}

如果你的项目是从githubclone下来的,那么可以选择省略后面的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里面找包,而不是从本地找包


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK