0. 前言

  • 最近加入鹅厂学习 k8s,组内使用 Go 1.11 以上的 go modules 管理依赖,因此整理了相关资料
  • 本文严重参考原文:初窥Go module

1. 传统 Golang 包依赖管理

  • Golang 设计深受 Google 主干开发模型影响:

    • 所有开发人员基于主干 trunk/mainline 开发:提交到 trunk 或从 trunk 获取最新的代码(同步到本地 workspace)
    • 版本发布时,建立 Release branch,release branch 实质上就是某一个时刻主干代码的快照
    • release branch 上 的 bug fix 和增强改进代码也通常是先在主干上提交(commit),然后再 cherry-pick 到 release branch 上

  • Golang 中的 go get 的设计深受 Google 内部单一代码仓库(single monorepo)和基于主干(trunk/mainline based)的开发模型的影响:只获取 trunk/mainline 最新版本
  • go get 获取的代码会放在 $GOPATH/src 下面,而 go build 会在 $GOROOT/src 和 $GOPATH/src 下面按照 import path 去搜索 package
  • 由于 go get 获取的都是各个 package repo 的 trunk/mainline 的代码,因此 Go 1.5 之前的 Go compiler 都是基于目标 Go 程序依赖包的 trunk/mainline 代码去编译的
  • 这样的机制带来的问题包括:
    • trunk/mainline 代码时刻变化,不同人不同时刻获取的代码可能不同(即不能实现 reproduceable build)
    • 依赖包的 trunk 演进可能会导致代码无法编译
  • 为了实现 reporduceable build,Go 1.5 引入了 govendor 机制
    • Golang 编译器会优先在 vendor 下搜索依赖的第三方包
    • 开发者将特定版本的依赖包存放在 vendor 下面并提交到代码库
    • 那么所有人理论上都会得到同样的编译结果,从而实现reporduceable build
  • 在Go 1.5 发布后的若干年,Gopher 们把注意力都集中在如何利用 vendor 解决包依赖问题
    • 从手工添加依赖到 vendor
    • 手工更新依赖,到一众包依赖管理工具的诞生:比如: govendor、glide 以及号称准官方工具的 dep
    • 努力地尝试着按照当今主流思路解决着诸如:“钻石型依赖”等难题
  • 正当 Gopher 认为 dep 将顺理成章地升级为 go toolchain 一部分的时候,vgo 横空出世
  • 在原 Go tools 上简单快速地实现 了Go 原生的包依赖管理方案 ,vgo 就是 go modules 的前身

2. go modules 简介

  • 通常我们会在一个仓库中创建一组 package,仓库的路径比如:github.com/bigwhite/gocmpp 会作为 go package 的导入路径(import path)
  • GOPATH 模式下,编译器会根据 package 路径在 $GOPATH/src 或者 vendor 下逐级目录匹配
  • Go 1.8 版本中,如果开发者没有显式设置 $GOPATH,Go 会赋予 GOPATH 一个默认值(在 linux 上为 $HOME/go)
  • Go 1.11 给这样的一组在同一仓库下面的 packages 赋予了一个新的抽象概念:module
  • 并启用一个新的文件 go.mod 记录 module 的元信息
  • 一个仓库对应一个 module 或者多个 module
  • 在 go modules 下,仓库顶层目录下会放置一个 go.mod 文件,每个 go.mod 文件定义了一个 module,而放置 go.mod 文件的目录被称为 module root 目录(通常对应一个仓库的 root 目录,但不是必须的)
  • module root 目录以及其子目录下的所有 packages 均归属于该 module,除了那些自身包含 go.mod 文件的子目录
  • 在 go modules 下,Golang 编译器将不再在 GOPATH 下面以及 vendor 下面搜索目标程序依赖的第三方 packages

3. 尝试使用 go modules

  • 设置环境变量 GO111MODULE:

    • GO111MODULE=off:无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包
    • GO111MODULE=on:模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod 下载依赖
    • GO111MODULE=auto:在 $GOPATH/src 外面且根目录有 go.mod 文件时,开启模块支持
  • 在使用模块的时候,GOPATH 是无意义的,不过还是会把下载的依赖储存在 $GOPATH/pkg/mod 中,也会把 go install 的结果放在 $GOPATH/bin
  • 在 ~/test 下创建 hello 目录,然后写入 hello.go(此时不在 $GOPATH 中)

// hello.go
package mainimport "bitbucket.org/bigwhite/c"func main() {c.CallC()
}

View Code

  • 在 ~/test/hello 下创建 go.mod:

// go.mod
module hello

View Code

  • 构建 hello.go:

$ go build hello.go
go: finding bitbucket.org/bigwhite/c v1.3.0
go: downloading bitbucket.org/bigwhite/c v1.3.0
go: extracting bitbucket.org/bigwhite/c v1.3.0
go: finding bitbucket.org/bigwhite/d v1.2.0
go: downloading bitbucket.org/bigwhite/d v1.2.0
go: extracting bitbucket.org/bigwhite/d v1.2.0$ ./hello.exe
call C: v1.3.0--> call D:call D: v1.2.0--> call D end

View Code

  • 查看 go.mod:

$ cat go.mod
// go.mod
module hellogo 1.12require bitbucket.org/bigwhite/c v1.3.0 // indirect

View Code

  • indirect 指不是由主 mod 直接引用的包,而是由其他 mod 间接引用的包
  • 如果之后新增了该 mod 的直接引用,会删除上面的间接引用
  • go compiler 将下载的依赖包缓存在 $GOPATH/pkg/mod 下面:

$ pwd
/e/Coding/Golang/go/pkg/mod/cache/download$ ls
bitbucket.org/     github.com/   golang.org/         gopkg.in/  sigs.k8s.io/
cloud.google.com/  go.uber.org/  google.golang.org/  k8s.io/

View Code

  • 具体执行:

$ ./hello.exe
call C: v1.3.0--> call D:call D: v1.2.0--> call D end

View Code

4. 参考文献

  • 初窥Go module
  • Go Module 入门使用

转载于:https://www.cnblogs.com/wangao1236/p/11002871.html

Golang(八)go modules 学习相关推荐

  1. 孤荷凌寒自学python第八十一天学习爬取图片1

    孤荷凌寒自学python第八十一天学习爬取图片1 (完整学习过程屏幕记录视频地址在文末) 通过前面十天的学习,我已经基本了解了通过requests模块来与网站服务器进行交互的方法,也知道了Beauti ...

  2. 花书+吴恩达深度学习(十八)迁移学习和多任务学习

    目录 0. 前言 1. 迁移学习 2. 多任务学习 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔~我会非常开心的~ 花书+吴恩达深度学习(十八)迁移学习和多任务学习 花书+吴恩达深度学习(十 ...

  3. (2012.01.12-2012.04.01)八十二天的学习小记

    (2012.01.12-2012.04.01)八十二天的学习小记   哈哈,原来又是过了八十二个日子了,真快啊~这次发的学习小记日期记录时间有点长,回看1月份的东西,原来已经隔了八十多个日子了,对于这 ...

  4. 推荐八个技术学习网站

    推荐八个技术学习网站 写在前边的话 八个纯技术学习好网站 写在前边的话 我们相信努力学习一定会有收获,但是方法不当,既让人身心疲惫,也没有切实的回报.在众多互联网技术网站中,各有各的好,经过网上收集整 ...

  5. 抢票 | AI未来说学术论坛第八期 深度学习特别专场

    AI已来,而你来不来!? 人工智能论坛如今浩如烟海,有硬货.有干货的讲座却百里挑一."AI未来说"青年学术论坛第八期如约而至.来自中国科学院大学的"AI小鸭学院" ...

  6. 20165223《Java程序设计》第八周Java学习总结

    教材学习内容总结 第12章-JAVA多线程机制 要点 Java中的线程 Thread类与线程的创建 线程的常用方法 线程同步 协调同步的线程 线程联合 GUI线程 计时器线程 教材学习中的问题和解决过 ...

  7. C/C++基础查漏补缺(八)----------寒假学习笔记(八)

    寒假C语言基础查漏补缺笔记(八) 本系列文章是基于自身的编程基础而编写的,其内容并非适用于所有人,请海涵~ 不过内容应该包括了所有的考点.用法,初学C/C++的大学生或者noip入门级选手可以以此作为 ...

  8. [goa]golang微服务框架学习--安装使用

    当项目逐渐变大之后,服务增多,开发人员增加,单纯的使用go来写服务会遇到风格不统一,开发效率上的问题. 之前研究go的微服务架构go-kit最让人头疼的就是定义服务之后,还要写很多重复的框架代码,一直 ...

  9. 燕十八公益教程-学习感想

    燕十八老师的公益教程第二期已经开了有一段时间了,也跟老师从头学习了很多东西,老师的讲课很精彩,每讲一个知识点都从生活中举例子,浅显易懂,深入浅出. 每天我8点到开始,都是我期待的时间段,虽说放弃了娱乐 ...

  10. 八年英语学习路及后序

    原文地址:http://haofly.net/blog/2014/01/05/about-english/ 2013年最后一个月,六级终于考完了,仔细回想一下,大概是在2006年上初中后才开始学习英语 ...

最新文章

  1. 分表需要解决的问题 基于MyBatis 的轻量分表落地方案
  2. java+flash在线拍照和编辑,保存到服务器(Spring3.2.2+swf+jquery)
  3. oracle日期导出mysql_oracle的数据导入到mysql中,遇到一个时间转换问题
  4. 正则表达式贪婪模式及最短匹配
  5. Facebook开源算法代码库,轻松复现前沿视频理解模型
  6. Cocos Creator JS 时间戳日期转换
  7. 【机器学习基础】说模型过拟合的时候,说的是什么?
  8. C++编译单元 内部链接 外部链接
  9. vba mysql连接字符串_分享一个VBA连接mysql数据库的方法
  10. eclipse导入myeclipse项目
  11. Android 渗透测试学习手册 第八章 ARM 利用
  12. 武汉群硕面试心得体会(上)
  13. 读取页面上所有的checkbox
  14. [转]C#操作Excel开发报表系列整理
  15. 编程之美 1.4买书问题常数时间空间解法
  16. CUDA的内存泄露问题及解决办法
  17. go c 语言,c语言与go语言的区别有哪些
  18. Python学习手册(第4版).pdf
  19. 西南科技大学OJ题 利用二叉树中序及先序遍历确定该二叉树的后序序列0984
  20. 配置管理工具Puppet入门介绍:1 :安装与设定

热门文章

  1. Cmdkey 凭证管理器工具
  2. xp系统运行asp.net时候出现“服务器应用程序不可用”,vs2005无法启动调试
  3. 包邮送几本Python和R语言的数据分析挖掘书籍
  4. R语言数据清洗实战——高效list解析方案
  5. [转]史上最最最详细的手写Promise教程
  6. openstack: No valid host was found. There are not enough hosts available
  7. 使用CMD实现批量重命名[转]
  8. shell脚本只运行一个实例
  9. uploadify 3.1 的修改
  10. Amoeba Architecture