Go Module 构建模式
使用 Go Module 构建 Go 程序只需要简单的三步:
go mod init 路径/路径 # 初始化当前文件夹,创建 go.mod 文件
go mod tidy # 增加缺少的 module,删除无用的 module
go build # 进行 Go 程序构建
相信很多小伙伴看到这段代码之后都会有自己的疑惑,我来分享一下自己的疑惑和解答吧。
init 后面跟的路径是什么?
这个我也还没搞懂,看网上说有命名空间的意思。这个路径在什么地方会用到呢?我猜和包的发布有关,之后学到后面的内容,再来更新这个地方的知识吧。
Go Module 怎么知道用哪个版本
可以看得到经过 go mod tidy
命令生成的 go.mod 文件的 require 段中依赖的版本号都符合 vX.Y.Z 的格式。
//go.mod
module hellomodule
go 1.17
require (
github.com/valyala/fasthttp v1.31.0
go.uber.org/zap v1.19.1
)
require (
github.com/andybalholm/brotli v1.0.2 // indirect
github.com/klauspost/compress v1.13.4 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
)
这种 vX.Y.Z 的格式,就是 Go 的语言版本号规范。v 是版本号前缀、X 为主版本号(major)、Y 为次版本号 (minor)、Z 为补丁版本号 (patch)。这里有个重点,在主版本号相同的情况下,次版本号大都是向后兼容次版本号小的版本。补丁版本号也不影响兼容性。这也就意味着 Go Module 只用关注主版本号就行,次版本号和补丁版本号如果没有特别指定,理所当然的会使用最新的。
那么怎么指定大版本号呢?这里 Go Module 创新性地将包主版本号引入到包导入路径中,例如,我们可以像下面这样导入 logrus v2.Y.Z 版本依赖包。
// main.go
import "github.com/sirupsen/logrus/v2"
这里也有个重点,当主版本号为 0 或 1 的时候,在包导入路径中省略掉版本号信息。也就是说像下面这样的写法,其实导入的就是 v1 版本。
// main.go
import "github.com/valyala/fasthttp"
如何自定义版本
主版本的修改请过包导入路径中的版本号信息来控制
// main.go
import "github.com/sirupsen/logrus/v 这个地方确定主版本号"
在 main.go 文件里修改完后,执行 go mod tidy
命令即可。
至于,次版本号、补丁版本号。默认情况下,使用 go mod tidy
命令会选择依赖项的“最新最大 (Latest Greatest) 版本”,因为没有兼容问题,还修复了漏洞,何乐不为。但出于某些原因,就是想用旧的版本怎么办?最简单的方法就是直接修改 go.mod
文件里的次版本号、补丁版本号信息,然后再使用 go mod tidy
命令。这样就会使用你修改过的指定版本。这里提供两个命令:
go list -m -versions github.com/sirupsen/logrus # 可以查看某个包的所有发布的历史版本
go mod edit -require=github.com/sirupsen/logrus@v1.7.0 # 如果不想打开 go.mod 文件,可以用这个直接修改某个包的依赖版本
想取消版本指定,在 go.mod 里删除对应的包信息,然后执行 go mod tidy
命令即可。
不再依赖某包,在 main.go 里删除包导入路径,然后使执行go mod tidy
命令即可。