go modules 简单上手

综述

go modules 是Go语言官方在1.11中加入的功能,虽然现在叫“实验性功能”,但应该就是官方钦定的了。GOPATH将在1.12弃用掉。

go modules 在我看来解决了两个原本很头疼的问题:

  1. 项目依赖的第三方包的版本无法控制
  2. 项目必须放在GOPATH里

对于第三方包的版本控制,如果用go modules的话,就可以指定第三方包的版本,e.g.

1
github.com/gin-gonic/gin v1.3.0

如果不固定版本的话,一旦第三方库在更新版本出现向后不兼容(例如satori/go.uuid这个库就有这种事),每次都拉取最新的版本,轻则编译无法通过,重则出现运行时的问题。

使用

首先需要安装go 1.11

如已安装,对于已有的项目,只需要

1
go mod init [project_name]

在工程目录下会生成一个go.mod文件,现在这个文件里只有一行module名。

然后执行任意go命令,比如go list,会自动下载本项目所需要的包,并且会自动填充go.mod文件。下载下来的包,会存到$GOPATH/pkg/mod/下边,但是会区分版本,而不是混在一起。e.g.

1
$GOPATH/pkg/mod/github.com/buger/jsonparser@v0.0.0-20181115193947-bf1c66bbce23

如果遇到了奇怪的问题,可以尝试设置环境变量GO111MODULE=on。这个值默认情况下是auto,理论上,你在非GOPATH路径下执行go mod,都会触发go module的功能。

此时如果打开go.mod,可以看到文件中已经指定了第三方包的版本。例如github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b。后边的版本是可以手动指定的,比如可以设置为master或者想要的版本。

举例:我在使用go.uuid这个包的时候,遇到了一个奇怪的版本问题。我第一次执行go list的时候,Golang自动给我下载的包版本是v1.2.0,但这个版本存在不兼容的问题。我在go.mod中将版本手动填写为master然后再执行go list,Golang将go.uuid的版本自动更新为了v1.2.1-xxx(当前的最新版本),问题消除。原理还不太清楚,但肯定是可以通过go.mod来控制第三方包的版本。

工程目录下,还会生成一个go.sum文件,可以做hash校验。

参考资料