1. 简介

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模式

2. 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.com/google/uuid目录中存储的是完整的仓库。

3.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)中的信息。

4.包名大小写敏感问题

有时我们使用的包名中会包含大写字母,比如github.com/Azure/azure-sdk-for-goGOMODULE模式下,在存储时会将包名做大小写编码处理,即每个大写字母将变与!+相应的小写字母,比如github.com/Azure包在存储时将会被放置在$GOPATH/pkg/mod/github.com/!azure目录中。

需要注意的是,GOMODULE模式下,使用go get命令时,如果不小心将某个包名大小写搞错,比如github.com/google/uuid写成github.com/google/UUID时,在存储依赖包时会严格按照go get命令指示的包名进行存储。

如下所示,使用大写的UUID:

[root@wsl-maoyifei]# 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/目录下将会多出一个d@v1.0.0"">!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指令中,所以在实际使用时应该尽量避免。

最新文章

  1. CSS中position小解
  2. jquery实现AJAX的4种方法
  3. javascrpt插入html中中文字符乱码问题记录
  4. C#的库存管理之旅的别样意义
  5. px和em
  6. MongoDB的快速手动安装
  7. CentOS安装Xen
  8. [King.yue]Ext.NET相比WebForm的优势
  9. llinuxs介绍与常用命令
  10. 关于UTF8文件带BOM头可能会引起的错误解析
  11. [转帖]优化IMPDP/EXPDP导入导出速度
  12. EF CodeFirst系列(9)---添加初始化数据和数据库迁移策略
  13. day014 模块
  14. Mock.js的简单使用
  15. 第三周结对项目--小学生四则运算CAI软件汇报及总结(UI/web)
  16. Sql注入基础原理介绍
  17. Core中使用Hangfire
  18. [转载] C++的那些事:你真的了解引用吗
  19. SQL面试题及答案
  20. Intel酷睿前世今生(二)

热门文章

  1. .net core番外第2篇:Autofac的3种依赖注入方式(构造函数注入、属性注入和方法注入),以及在过滤器里面实现依赖注入
  2. C# 连接MySQL数据库 ,查询条件中有中文时,查询不出结果
  3. ASM入网小助手卸载
  4. 深入刨析tomcat 之---第23篇 聊一下web容器的filter配置和defaultservet
  5. mapGetters 的作用__为什么mapGetter前面有...(三个点是去掉{}的作用)
  6. JS对DOM的操作优化法则
  7. Aria2 任意文件写入
  8. 字符串对象 API
  9. Spring Cloud分区发布实践(3) 网关和负载均衡
  10. 官宣|VS Code 1.59 发布!Terminal 可以跨窗口移动了!