总览
- Go 专家编程 go mod 依赖包存储
在前面介绍
GOPATH
的章节中,我们提到
GOPATH
模式下不方便使用同一个依赖包的多个版本。在
GOMODULE
模式下这个问题得到了很好的解决。
GOPATH
模式下,依赖包存储在
$GOPATH/src
,该目录下只保存特定依赖包的一个版本,而在
GOMODULE
模式下,依赖包存储在
$GOPATH/pkg/mod
,该目录中可以存储特定依赖包的多个版本。
需要注意的是
$GOPATH/pkg/mod
目录下有个
cache
目录,它用来存储依赖包的缓存,简单说,
go
命令每次下载新的依赖包都会在该
cache
目录中保存一份。关于该目录的工作机制我们留到
GOPROXY
章节时再详细介绍。
接下来,我们使用开源项目
github.com/google/uuid
为例分别说明
GOPATH
模式和
GOMODULE
模式下特定依赖包存储机制。在下面的操作中,我们会使用
GO111MODULE
环境变量控制具体的模式:
export GO111MODULE=off
切换到GOPATH
模式export GO111MODULE=on
切换到GOMODULE
模式。
1. GOPATH 依赖包存储
为了实验
GOPATH
模式下依赖包的存储方式,我们可以使用以下命令来获取
github.com/google/uuid
:
# export GO111MODULE=off
# go get -v github.com/google/uuid
在
GOPATH
模式下,
go get
命令会将依赖包下载到
$GOPATH/src/google
目录中。
该命令等同于在
$GOPATH/src/google
目录下执行
git clone https://github.com/google/uuid.git
,也就是
$GOPATH/src/google/uuid
目录中存储的是完整的仓库。
2. GOMODULE 依赖包存储
为了实验
GOMODULE
模式下依赖的存储方式,我们使用以下命令来获取
github.com/google/uuid
:
# export GO111MODULE=on
# go get -v github.com/google/uuid
# go get -v github.com/google/[email protected]
# go get -v github.com/google/[email protected]
# go get -v github.com/google/[email protected]
在
GOMODULE
模式下,
go get
命令会将依赖包下载到
$GOPATH/pkg/mod
目录下,并且按照依赖包的版本分别存放。(注:
go get
命令不指定特定版本时,默认会下载最新版本,即v1.1.1,如软件包有新版本发布,实验结果将有所不同。)
此时
$GOPATH/pkg/mod
目录结构如下:
${GOPATH}/pkg/mod/github.com/google
├── [email protected]
├── [email protected]
├── [email protected]
相较于
GOPATH
模式,
GOMODULE
有两处不同点:
- 一是依赖包的目录中包含了版本号,每个版本占用一个目录;
- 二是依赖包的特定版本目录中只包含依赖包文件,不包含
.git
目录;
由于依赖包的每个版本都有一个唯一的目录,所以在多项目场景中需要使用同一个依赖包的多版本时才不会产生冲突。另外,由于依赖包的每个版本都有唯一的目录,也表示该目录内容不会发生改变,也就不必再存储其位于版本管理系统(如git)中的信息。
3. 包名大小写敏感问题
有时我们使用的包名中会包含大写字母,比如
github.com/Azure/azure-sdk-for-go
,
GOMODULE
模式下,在存储时会将包名做大小写编码处理,即每个大写字母将变与
!
+相应的小写字母,比如
github.com/Azure
包在存储时将会被放置在
$GOPATH/pkg/mod/github.com/!azure
目录中。
需要注意的是,
GOMODULE
模式下,我们使用
go get
命令时,如果不小心将某个包名大小写搞错,比如
github.com/google/uuid
写成
github.com/google/UUID
时,在存储依赖包时会严格按照
go get
命令指示的包名进行存储。
如下所示,使用大写的
UUID
:
[root@ecs-d8b6 uuid]# go get -v github.com/google/[email protected]
go: finding github.com v1.0.0
go: finding github.com/google v1.0.0
go: finding github.com/google/UUID v1.0.0
go: downloading github.com/google/UUID v1.0.0
go: extracting github.com/google/UUID v1.0.0
github.com/google/UUID
由于
github.com/google/uuid
域名不区分大小写,所以使用
github.com/google/UUID
下载包时仍然可以下载,但在存储时将会严格区分大小写,此时
$GOPATH/pkg/mod/google/
目录下将会多出一个
[email protected]
目录:
${GOPATH}/pkg/mod/github.com/google
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
在
go get
中使用错误的包名,除了会增加额外的不必要存储外,还可能会影响
go
命令解析依赖,还可能将错误的包名使用到
import
指令中,所以在实际使用时应该尽量避免。
版权归原作者 oceanweave 所有, 如有侵权,请联系我们删除。