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指令中,所以在实际使用时应该尽量避免。

Go版本管理--依赖包存储的更多相关文章

  1. 引入HBase依赖包带来的麻烦

    在一个项目里用到HBase做底层存储,使用maven来管理相关Jar包依赖,用maven来管理依赖包,特别不爽的就是他会将你引入Jar包自己的依赖都搞进来,经常会出现一些类和方法冲突找不到等状况.这次 ...

  2. golang使用vendor目录来管理依赖包

    Vendor目录介绍 随着Go 1.5 release版本的发布,vendor目录被添加到除了GOPATH和GOROOT之外的依赖目录查找的解决方案.在Go 1.6之前,你需要手动的设置环境变量GO1 ...

  3. SpringBoot 之Spring Boot Starter依赖包及作用

    Spring Boot 之Spring Boot Starter依赖包及作用 spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. spri ...

  4. golang包管理工具及环境管理工具;如何下载外网的依赖包

    简介: golang的包管理工具类似于java的maven.python的pip.js的npm,可以实现依赖包的统一管理:有很多:govendor.godep.glide,挑一个自己喜欢的用吧.mac ...

  5. 离线下载解决Nuget程序包及其依赖包的方法

    由于使用的一台电脑没有联网,但是需要asp.net core项目时使用到一个package,于是在nuget.org上手动下载.但是最后发现,依赖的包实在太多,手动下载太费时.于是晚上花时间研究了一下 ...

  6. Caffe实战三(依赖包解析及环境配置)

    前面的文章使用的软件环境是开始时通过apt-get命令所安装的,本文将通过编译源码的方式重新配置一个可迁移的软件环境.(参考:<深度学习 21天实战Caffe> 第五天 Caffe依赖包解 ...

  7. java打jar包与找不到依赖包详解

    eclipse打jar包与找不到依赖包详解 eclipse打工具jar 1.项目右键-->export -->搜索java 2.选择JAR file 3.打包 eclipse打包可执行ja ...

  8. flutter如何使用配置文件pubspec.yaml(位于项目根目录)来管理第三方依赖包

    官方文档 在软件开发中,很多时候有一些公共的库或SDK可能会被很多项目用到,因此,将这些代码单独抽到一个独立模块,然后哪个项目需要使用时再直接集成这个模块,便可大大提高开发效率.很多编程语言或开发工具 ...

  9. 为什么在SpringBoot+maven的项目中,所引入的依赖包可以不指定依赖的版本号?

    当在Springboot项目中引入了spring-boot-starter-parent,则可以不用引入依赖包版本号,比如: <parent> <groupId>org.spr ...

随机推荐

  1. Selenium3自动化测试【20】CSS定位元素

    CSS 指层叠样式表 (CascadingStyleSheets),CSS一种用来表现HTML或XML等文件样式的计算机语言,其能够灵活的为页面提供丰富样式的风格. CSS使用选择器为页面元素绑定属性 ...

  2. 为什么要配置java环境变量

    Java环境变量,真的还有必要配吗? 作为年龄上堪称老鸟而技术上却是菜鸟的老菜鸟,为了祖国的编程事业,不惜拿出一个月工资,淘了一台配置稍高的二手笔记本,打算与老笔记本中的撸啊撸片彻底说再见,誓要在新机 ...

  3. [源码解析] 机器学习参数服务器ps-lite (1) ----- PostOffice

    [源码解析] 机器学习参数服务器ps-lite 之(1) ----- PostOffice 目录 [源码解析] 机器学习参数服务器ps-lite 之(1) ----- PostOffice 0x00 ...

  4. Hyper-V下Internal vSwitch的配置和Linux虚拟机的SSH连接

    最近工作中要在Windows Server 2016/Hyper-V 10中运行Ubuntu16实例,需要制作出"即插即用"的镜像文件,也就是安装好后即可从外部SSH进去.之前我使 ...

  5. PXE高效装机

    目录 一.PXE概述 二.PXE的优点 三.搭建PXE的前提 四.部署PXE远程安装服务 1.安装TFTP服务 2.修改TFTP服务的配置文件,并开启服务 关闭防火墙 3.安装DHCP服务 4.修改D ...

  6. XCTF-simple unpack

    题目提示这是一个加壳的二进制文件,拖到exeinfope,是UPX壳. 这里我们用linux命令upx -d脱壳. 脱完壳之后拉入ida64中分析.找到main函数,可以看到这一句可以是输出flag的 ...

  7. MongoDB 批量插入和循环插入性能测试

    一万条数据批量插入和循环插入 循环插入 var startTime = (new Date()).getTime() var db = connect('log') for(var i = 0;i&l ...

  8. Python开发篇——基于React-Dropzone开发上传组件

    这次我要讲述的是在React-Flask框架上开发上传组件的技巧.我目前主要以React开发前端,在这个过程中认识到了许多有趣的前端UI框架--React-Bootstrap.Ant Design.M ...

  9. Android Hello World程序开发过程

    按照Building Your First App,详细过程如下: 安装SDK(如果网速慢,需要用离线安装的方法,见笔记 离线安装Android SDK的方法 ): 采用命令行开发方法(不用装Ecli ...

  10. PTA 朋友圈 (25 分) 代码详解 (并查集)

    1.题目要求: 某学校有N个学生,形成M个俱乐部.每个俱乐部里的学生有着一定相似的兴趣爱好,形成一个朋友圈.一个学生可以同时属于若干个不同的俱乐部.根据"我的朋友的朋友也是我的朋友" ...