【Go mod 学习之依赖包存储篇】go get 下载的包存储在哪?

  • Post author:
  • Post category:其他




总览

在前面介绍

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/uuid@v1.0.0
# go get -v github.com/google/uuid@v1.1.0
# go get -v github.com/google/uuid@v1.1.1



GOMODULE

模式下,

go get

命令会将依赖包下载到

$GOPATH/pkg/mod

目录下,并且按照依赖包的版本分别存放。(注:

go get

命令不指定特定版本时,默认会下载最新版本,即v1.1.1,如软件包有新版本发布,实验结果将有所不同。)

此时

$GOPATH/pkg/mod

目录结构如下:

${GOPATH}/pkg/mod/github.com/google
├── uuid@v1.0.0
├── uuid@v1.1.0
├── uuid@v1.1.1

相较于

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/UUID@v1.0.0
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/

目录下将会多出一个

!u!u!i!d@v1.0.0

目录:

${GOPATH}/pkg/mod/github.com/google
├── uuid@v1.0.0
├── uuid@v1.1.0
├── uuid@v1.1.1
├── !u!u!i!d@v1.0.0



go get

中使用错误的包名,除了会增加额外的不必要存储外,还可能会影响

go

命令解析依赖,还可能将错误的包名使用到

import

指令中,所以在实际使用时应该尽量避免。



版权声明:本文为qq_24433609原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。