go.mod、go.sum、go.work

72 阅读2分钟

使用modules依赖管理的好处是非常明显的:

  • 自动下载依赖包
  • 不需要将代码再放入$GOPATH/src
  • 所有来自第三方的包都会指定版本(使用dep是无法指定第三方包的版本的)
  • 对于已经转移的包,可以用replace在go.mod文件中替换,不需要修改代码

如何使用Modules

  1. 把 golang 升级到 1.11+ (现在已经到1.19了)
  2. 设置 GO111MODULE

GO111MODULE

GO111MODULE 有三个值:off, onauto(默认值)

  • GO111MODULE=off,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。

  • GO111MODULE=on,go命令行会使用modules,而一点也不会去GOPATH目录下查找。

  • GO111MODULE=auto,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:

    • 当前目录在$GOPATH/src之外且该目录包含go.mod文件
    • 当前文件在包含go.mod文件的目录下面。

当modules 功能启用时,依赖包的存放位置变更为$GOPATH/pkg,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。

注:使用go modules最好搭配go proxy一起使用,否则在go get一些包时会出现get不到的问题

go.mod

go mod命令

命令说明
downloaddownload modules to local cache(下载依赖包到本地缓存)
editedit go.mod from tools or scripts (编辑go.mod)
graphprint module requirement graph (打印模块依赖图)
initinitialize new module in current directory (在当前目录初始化go.mod)
tidyadd missing and remove unused modules(拉取缺少的模块,移除不用的模块)
vendormake vendored copy of dependencies(将依赖复制到vendor下)
verifyverify dependencies have expected content (验证依赖是否正确)
whyexplain why packages or modules are needed(解释为什么需要依赖)

通常在项目中我们通过go get或者是go install的方式拉取指定版本的依赖包: 执行 go get命令,在下载依赖包的同时还可以指定依赖包的版本

  • 运行go get -u命令会将项目中的包升级到最新的次要版本或者修订版本
  • 运行go get -u=patch命令会将项目中的包升级到最新的修订版本
  • 运行go get [包名]@[版本号]命令会下载对应包的指定版本或者将对应包升级到指定的版本

当然我们也可以先不go get,在最后go run main.go时,go.mod同样会自动查找依赖自动下载

go.mod关键字

命令字作用
module指定包的名字(路径)
require指定依赖项模块
replace替换依赖项模块
exclude忽略依赖项模块

进入go.mod文件中,基本都是这样的结构

1672195189653.png 注:indirect 表示这个库是间接引用进来的

go.sum

相较于go.mod,go.sum看上去就像是天书,可读性实在是太低,但是我们日常开发仍不得不要跟其打交道(通常是解决这个文件带来的合并冲突,或是想手动调整其中的内容)。

先下一个粗浅定义:go.sum就是依据hash来检测下载下来的依赖,是不是和该版本依赖复合

go.sum格式

go.sum的内容格式基本上是如图所示 1672196522087.png

go.sum的每一行都是一个条目,大致是这样的格式

xml
 代码解读
复制代码
<module> <version>/go.mod <hash>

或者

xml
 代码解读
复制代码
<module> <version> <hash>
<module> <version>/go.mod <hash>

其中module是依赖的路径, version是依赖的版本号,hash是以h1开头的字符串,表示生成checksum的算法是第一版的hash算法(sha256)