GOPATH

早期Go语言使用GOPATH来进行依赖管理。安装Go语言之后,我们需要配置环境变量,GOROOTGOPATHGOROOT代表Go语言的安装目录,GOPATH代表你的工作路径。

GOPATH下的目录结构

  • – bin 存放编译后生成的二进制可执行文件
  • – pkg 存放编译后生成的 .a 文件
  • – src 存放项目的源代码,可以是你自己写的代码,也可以是你 go get 下载的包
GOPATH
├── bin
├── pkg
└── src├── projectA├── projectB└── projectC

将你的包或者别人的包全部放在 $GOPATH/src 目录下进行管理的方式,我们称之为GOPATH模式。

使用 GOPATH 管理的缺点

版本管理问题

GOPATH 根本没有版本的概念,GOPATHsrc下只能有一个版本存在,所以不能实现多版本控制。

如果你所应用的库需要升级,那就是全局升级,所以涉及这个库的服务在下一次编译中都会使用新的库,这是一件很危险的事情。版本管理非常重要,自己应该管理好自己的引用库。

协同开发问题

当其他的开发者get到源码进行修改的时候,你无法保证他下载的包是不是你所期望的版本,这及有可能导致服务出错,且很难查找原因。

GOVENDOR

为了解决 GOPATH 方案下不同项目下无法使用多个版本库的问题,Go v1.5 开始支持 vendor 。我们之前是所有项目都放到GOPATHsrc目录下进行管理,所有项目的依赖都在这里寻找。并且只能存在一个版本。但是每个项目可能引用的第三方库的版本不一样,我们需要满足多版本控制。

于是,现在可以在每个项目下建立vector目录,每个项目所需的依赖都只会下载到自己vendor目录下,项目之间的依赖包互不影响。

如果该项目要查找引用的包,那么会按照如下顺序进行搜索

  • 先搜索当前包下的vendor目录
  • 向上级目录搜搜,直到src下的vendor目录
  • GOROOT目录下搜索
  • GOPATH目录下搜索
 .
└── GOPATH├── bin├── pkg└── src├── projectA│   ├── handler│   ├── server.go│   └── vendor├── projectB│   ├── handler│   ├── server.go│   └── vendor└── projectC├── handler├── server.go└── vendor

使用 GO VENDOR 管理的缺点

假设一个Project依赖AB两个package,然后A依赖第三方的package v1B依赖第三方的package v2,这就会导致冲突。

仍然需要在GOPATH目录下。

GO MOD

之后Go引入了go modgo mod不在依赖$GOPATH目录,因此我们可以在其他地方创建项目,而不一定要在$GOPATH/src目录下。

go mod模式可以手动开启关闭,通过GO111MODULE实现。

  • GO111MODULE=off禁用模块支持,编译时会从GOPATHvendor文件夹中查找包。
  • GO111MODULE=on启用模块支持,编译时会忽略GOPATHvendor文件夹,只根据 go.mod下载依赖。
  • GO111MODULE=auto,当项目在$GOPATH/src外且项目根目录有go.mod文件时,自动开启模块支持。

使用go env查看环境变量,可以看到GO111MODULE=on,说明我启动了go mod模式管理依赖

go env
PS D:\Go\workspaces\src> go env
set GO111MODULE=on
set GOPATH=D:\syz\study\computer_science\Go\workspaces
set GOPROXY=https://goproxy.cn,direct
set GOROOT=D:\Program Files (x86)\go

如何使用go mod

创建一个项目,在此文件夹下输入go mod init初始化(记得开启go mod模式),之后变会使用go mod模式管理。之后,会在你的目录下创建go.mod文件,编译后还会出现go.sum文件。

我们在简单的hello world程序下引入gin框架,可以看到go.sum文件出现了变动,go mod会将所有的依赖包安装在$GOPATH/pkg目录下。

go.mod文件

  • 第一行:模块的引用路径
  • 第二行:项目使用的 go 版本
  • 第三行:项目所需的直接依赖包及其版本
module testgo 1.13require github.com/gin-gonic/gin v1.7.7

go.sum文件

每一行都是由 模块路径模块版本哈希检验值 组成,其中哈希检验值是用来保证当前缓存的模块不会被篡改。hash 是以h1:开头的字符串,表示生成checksum的算法是第一版的hash算法(sha256)。

github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
...

有的包可能有两行

<module> <version> <hash>
<module> <version>/go.mod <hash>

那些有两行的包,区别就在于hash值不一行,一个是 h1:hash,一个是 go.mod h1:hash

h1:hashgo.mod h1:hash两者,要不就是同时存在,要不就是只存在 go.mod h1:hash。那什么情况下会不存在 h1:hash 呢,就是当Go认为肯定用不到某个模块版本的时候就会省略它的h1 hash,就会出现不存在 h1 hash,只存在 go.mod h1:hash 的情况。

注意

如果你开启了go mod模式,但是又没有go mod init,那么是无法进行依赖管理的,也不会按照GO PATH的方法进行依赖查找。

参考

  • (206条消息) golang中使用GOPATH模式和GoModule(gomod)模式的区别_SunkingYang的博客-CSDN博客_gopath和gomodule
  • 19. 一文搞懂 Go Modules 前世今生及入门使用 - 王一白 - 博客园 (cnblogs.com)

GOPATH,go vendor,go mod解析相关推荐

  1. go build不从本地gopath获取_Go包管理GOPATH、vendor、go mod机制

    简介 Golang 作为开源编程语言,在 2012 年编程语言 Go 1 发布之后,一直在不断发展,并伴随着云原生而广泛进入各大公司. 在互联网发展至今,软件系统不断膨胀. 各个编程语言也都逐步支持了 ...

  2. Go:包管理工具GOPATH、vendor、dep 、go module

    目录 Go包管理工具:前言 GOPATH vendor.dep Go modules Module 文件 go mod命令 Go modules使用步骤: go module的文件下载后位置: Go包 ...

  3. system和vendor分区挂载解析(Android O)

    首先我们知道init进程在运行时会调用自身,所以init进程分为stage1和stage2两个阶段,而分区挂载操作也分为两个阶段: stage1挂载操作是利用device tree中的配置项来读取配置 ...

  4. go build不从本地gopath获取_跟我一起学习go语言,包依赖管理工具go mod

    Go Module是Go会在1.12中正式推出的包管理机制. Go mod 简介 Golang一直存在一个被人诟病的问题是缺少一个官方的包依赖管理工具.从我个人的角度上来看存在两个问题: GOPATH ...

  5. go vendor 项目迁移到 mod 项目

    检查最新的 Golang 版本 你如果问我,为什么要用最新的?因为我们都是软件爱好者,我们应该渴望测试最新的技术! ( 顺便说一下,你可以用 Golang 1.11.X,但是您应该想知道为什么不使用最 ...

  6. win10下go mod 与gopath

    GOPATH跟GOROOT不同,它是我们指向的工作空间.我们运行一个项目时需要导入依赖包,默认情况下会在我们配置的go环境的src文件下去查找,比如本身自带的"fmt"," ...

  7. Go mod:一文教你真正用起来Go Module依赖管理

    Golang环境变量 GOROOT:go的安装路径 在~/.bash_profile中添加下面语句配置GOROOT环境变量 GOROOT=/usr/local/go export GOROOT 要执行 ...

  8. Go mod使用指南

    转自:https://studygolang.com/articles/31112?fr=sidebar 一.启用go mod go env -w GO111MODULE=on #开启 MODULE ...

  9. go mod 与 goproxy 的使用

    go modules 是 golang 1.11 新加的特性,Modules官方定义为: 模块是相关Go包的集合.modules是源代码交换和版本控制的单元. go命令直接支持使用modules, 包 ...

最新文章

  1. 由于未能创建 Microsoft Visual C# 2008 编译器,因此未能打开项目 ...的解决方法...
  2. Python语言的有限状态机实现样例
  3. windbg !htrace 学习总结
  4. 代码高亮_微信公众号代码高亮美化工具 Markdown Nice
  5. 通用多表分页存储过程
  6. Winform中选取指定文件夹并获取其下所有文件
  7. 如何用苹果手机生成扫描件
  8. JVM 调优实战--常用JVM命令:jps/jinfo/jstat/jmap/jstack/jhat
  9. jwt令牌_jwt-cli:用于解码JSON Web令牌(JWT令牌)的Shell库
  10. spark算子_Spark篇之持久化算子
  11. c语言编程计算平分,用C语言编程平均分数
  12. 计算机网络2020秋--第三次测验
  13. xsd 生成 java 类_如何从Java类生成XSD
  14. make[1]: *** [storage/perfschema/unittest/CMakeFiles/pfs_connect_attr-t.dir/all] 错误 2 解决方法...
  15. “向死而生”的微信视频号,逆风翻盘的2020
  16. Navicat远程连接服务器mysql,先后报错10060,10061
  17. hdu1166敌兵布(线段树模板题)
  18. 解决easyui combobox赋值boolean类型的值时,经常出现的内容显示的value而不是text的bug...
  19. 【Git】版本控制管理(第二版) 前言 第一章 第二章
  20. WhatsApp电脑版和WhatsApp网页版区别?

热门文章

  1. 医院内科七名医生值班,根据规定给出排班表
  2. 5 个 JavaScript 轮播库
  3. NOIP 提高组 复赛 历年 试题
  4. jdbc mysql是什么意思_什么是JDBC?
  5. 验证码是自动化的天敌?看看大神是怎么解决的
  6. 基于8051单片机实现电子时钟+数字秒表设计
  7. Linux设备驱动-kmalloc
  8. 冰封王座1.20(转载)
  9. 自贡计算机学校,自贡计算机电子信息职业技术学校2019年招生简介
  10. java中的抽象类和接口可以实例化吗?,它们可以有构造方法吗?(扩展:接口和抽象类的区别)