接触Go Modules

Go Modules特性是在go1.11开始加入的, 写这篇文章时官方刚刚发布了go1.11Beta3版本,如果你的go版本低于1.11则需要更新你的go tools。

module具体指的是什么

按照官方文档的说法, module是一个带版本信息的package集合,它们之间的关系如下图:

module、package、version-control repository 三者之间的关系

module之间没有父子关系,它们都是独立的。

module声明方式

go module使用一个名叫go.mod的文件来定义你的module,该文件记录module的一些基本信息。 module目录可以不在GOPATH下,Go Tools也能识别。

go.mod文件内容示例:

module blog 

require (
	github.com/gitwillsky/slimgo v1.0.0
	github.com/pkg/errors v0.8.0
)

关键字module

用来定义module的路径(非文件系统路径),这个路径可以定义为以下几种形式:

example.com/my/module
example.com/my/module/v2
my/module // 本地module
module

关键字require

用来声明该module所依赖的其他module(package),声明以后,每当执行go tools都会检查依赖的完整性并自动下载依赖。

即使你不在go.mod中声明依赖,go tools也会在执行时自动检查代码的import块并自动将没有声明的modue(package)写入go.mod文件,依赖版本默认为最后的Release版本。

module的版本

go module规定 module必须按照 v(major).(minor).(patch) 的形式来定义版本(Release tag),其中major如果大于2则必须同时在module path中指出,比如:me.io/my/mod/v2

依赖同一模块不同版本时如何选择?

go tools 从仓库拉取依赖的时候,使用minimal version selection算法:分析go.modrequire, 在major相同的情况下,选取requireminor最大的那个版本作为依赖模块的版本。

更新依赖版本

更新minor版本:

$ go get -u 

更新patch版本:

$ go get -u=patch

更新到指定版本:

$ go get github.com/gorilla/mux@latest
$ go get github.com/gorilla/mux@master
$ go get github.com/gorilla/mux@v1.6.2
$ go get github.com/gorilla/mux@'<v1.6.2'

如何创建一个module

  1. 进入即将创建module的根目录

    $ cd $GOPATH/src/<project path>
    $ export GO111MODULE=on
    

    $ cd <project path outside $GOPATH/src>
    
  2. 如果之前该工程由dep等依赖管理工具管理,则使用下面的命令创建:

    go mod init 
    

    go tools会自动分析之前的依赖信息并写入go.mod文件。

    或者,使用下面的命令来手动新建一个空的go.mod文件:

    go mod init module_path
    
  3. 执行go build 命令,让go tools分析module的源代码,找出在go.mod文件中没有声明的module并自动添加进去。

下载的依赖存放在什么地方?

$GOPATH/pkg/mod/cache/ 目录下

使用感受

  • go module给go的依赖管理增加了版本功能。
  • gopath不再显得那么僵硬了。

参考