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. FreeRTOS-01-任务相关函数

    3 任务相关API函数 任务相关函数如下: 任务创建和删除API函数 任务创建和删除实验(动态方法) 任务创建和删除实验(静态方法) 任务挂起和恢复API函数 任务挂起和恢复实验 3.1 任务创建AP ...

  2. 微信小程序云开发-云函数-创建云函数

    一.检查云函数环境 检查云函数环境时候,鼠标右键点击查看当前环境.如果存在多个云开发环境,要确保云函数的当前环境要与app.js中evn的环境值一致. 如果不一致,则鼠标右键切换当前云开发环境.(如果 ...

  3. 微信小程序云开发-数据库-用户删除数据

    一.在商品详情页添加[删除单条数据]按钮 进入goodDetail.wxml页面,添加[删除单条数据]按钮,绑定点击事件removeGood()  二.进入goodDetail.js文件,定义remo ...

  4. Windows配置深度学习环境详细教程(一):安装Pycharm和Miniconda、conda环境介绍

    序言 对于想要入门Python或者深度学习的初学者而言,配置环境一直是一个令人头疼的问题.相信有许多人经历过安装第三方包失败,安装好了却在使用中报错,安装CUDA.tensorflow.pytorch ...

  5. 什么是TCP?什么是TCP协议?

    一.什么是TCP >>>TCP是一种传输控制协议,是面向连接的.可靠的.基于字节流之间的传输层通信协议 >>>在因特网协议族里面,TCP层是在IP层上面,应用层下面 ...

  6. odoo里面context用法

    原文转自:https://www.cnblogs.com/zhaoweihang/p/9698852.html <field name="partner_id" string ...

  7. 手脱UPX壳的方法

    0X00    了解 upx UPX作为一款元老级PE加密壳,在以前的那个年代盛行,著名病毒[熊猫烧香]就是使用这款加密壳. 0X01    单步跟踪法 就是使用ollydbg加载程序后,按F8进行单 ...

  8. springboot自定义ObjectMapper序列化、配置序列化对LocalDateTime的支持

    背景 问题1:项目中使用默认自带的jackson进行前后端交互,实现数据对象的序列化和反序列化,默认的ObjectMapper采用小驼峰的格式,但是调用其他业务的http接口时,ObjectMappe ...

  9. time_formatter writeup

    攻防世界time_formatter writeup UAF漏洞和命令注入. 前置知识 1.strdup函数 char * __strdup(const char *s) { size_t len = ...

  10. RHCE_DAY04

    sed流式编辑器 sed是一个非交互的文本编辑器,实现的功能跟vim相同,主要是对文件内容进行输出.删除.替换.复制.剪切.导入.导出等功能 命令格式1:前置命令 | sed [选项] '[指令]' ...