1. 版本选择机制

使用go get <pkg>来获取某个依赖,如果没有特别指定依赖的版本号,go get会自动选择一个最优版本,并且如果本地有go.mod文件的话,还会自动更新go.mod文件.

事实上除了go getgo buildgo mod tidy也会自动帮我们选择依赖的版本。这些命令选择依赖版本时都遵循一些规则,本节我们就开始介绍Go module涉及到的版本选择机制。

2.依赖包版本约定

2.1 Go module 之前版本兼容性

Go v1.11(开始引入Go module的版本)之前,Go 语言建议: 依赖包需要保持向后兼容,这包括可导出的函数、变量、类型、常量等不可以随便删除

以函数为例,如果需要修改函数的入参,可以增加新的函数而不是直接修改原有的函数。

如果确实需要做一些打破兼容性的修改,建议创建新的包。

比如仓库github.com/RainbowMango/xxx中包含一个package A,此时该仓库只有一个package:

github.com/RainbowMango/xxx/A

那么其他项目引用该依赖时的import 路径为:

import "github.com/RainbowMango/xxx/A"

如果该依赖包需要引入一个不兼容的特性,可以在该仓库中增加一个新的package A1,此时该仓库包含两个包:

  • github.com/RainbowMango/xxx/A
  • github.com/RainbowMango/xxx/A1

那么其他项目在升级依赖包版本后不需要修改原有的代码可以继续使用package A,如果需要使用新的package A1,只需要将import 路径修改为import "github.com/RainbowMango/xxx/A1"并做相应的适配即可。

2.2 Go module 之后版本兼容性

从Go v1.11版本开始,随着Go module特性的引入,依赖包的兼容性要求有了进一步的延伸,Go module开始关心依赖包版本管理系统(如Git)中的版本号。尽管如此,兼容性要求的核心内容没有改变:

  • 如果新package 和旧的package拥有相同的import 路径,那么新package必须兼容旧的package;
  • 如果新的package不能兼容旧的package,那么新的package需要更换import路径;

在前面的介绍中,我们知道Go module 的go.mod中记录的module名字决定了import路径。例如,要引用module module github.com/renhongcai/indirect中的内容时,其import路径需要为import github.com/renhongcai/indirect

在Go module时代,module版本号要遵循语义化版本规范,即版本号格式为v<major>.<minor>.<patch>,如v1.2.3。当有不兼容的改变时,需要增加major版本号,如v2.1.0。

Go module规定,如果major版本号大于1,则major版本号需要显式地标记在module名字中,如module github.com/my/mod/v2。这样做的好处是Go module 会把module github.com/my/mod/v2module github.com/my/mod视做两个module,他们甚至可以被同时引用。

另外,如果module的版本为v0.x.xv1.x.x则都不需要在module名字中体现版本号。

3. 版本选择机制

Go 的多个命令行工具都有自动选择依赖版本的能力,如go build 和go test,当在源代码中增加了新的import,这些命令将会自动选择一个最优的版本,并更新go.mod文件。

需要特别说明的是,如果go.mod文件中已标记了某个依赖包的版本号,则这些命令不会主动更新go.mod中的版本号。所谓自动更新版本号只在go.mod中缺失某些依赖或者依赖不匹配时才会发生。

3.1 最新版本选择

当在源代码中新增加了一个import,比如:


import "github.com/RainbowMango/M"

如果go.mod的require指令中并没有包含github.com/RainbowMango/M这个依赖,那么go build 或go test命令则会去github.com/RainbowMango/M仓库寻找最新的符合语义化版本规范的版本,比如v1.2.3,并在go.mod文件中增加一条require依赖:

require github.com/RainbowMango/M v1.2.3

这里,由于import路径里没有类似于v2或更高的版本号,所以版本选择时只会选择v1.x.x的版本,不会去选择v2.x.x或更高的版本。

3.2 最小版本选择

有时记录在go.mod文件中的依赖包版本会随着引入其他依赖包而发生变化。

如下图所示: M最新版本是v1.5.0

Module A 依赖 Module M的v1.0.0版本,但之后 Module A 引入了 Module D,而Module D 依赖 Module M的v1.1.1版本,此时,由于依赖的传递,Module A也会选择v1.1.1版本。

需要注意的是,此时会自动选择最小可用的版本,而不是最新的tag(v1.5.0)版本。

Go版本依赖--版本选择机制的更多相关文章

  1. Spring IO Platform 解决Spring项目组合中版本依赖

    简介: Spring IO Platform是Spring官网中排第一位的项目.它将Spring的核心API集成到一个适用于现代应用程序的平台中.提供了Spring项目组合中的版本依赖.这些依赖关系是 ...

  2. Maven 3-Maven依赖版本冲突的分析及解决小结 (阿里,美团,京东面试)

    举例A依赖于B及C,而B又依赖于X.Y,而C依赖于X.M,则A除引B及C的依赖包下,还会引入X,Y,M的依赖包(一般情况下了,Maven可通过<scope>等若干种方式控制传递依赖).这里 ...

  3. yarn or npm 版本固化如何选择

    前言 作为前端开发者,npm这个包管理工具的重要性显而易见.优点不再表述,但一些缺点是为使用者诟病比较多的:速度慢.版本控制.下面主要讨论下npm的版本固化问题,即lock文件. npm语义化版本管理 ...

  4. Maven依赖版本冲突的分析及解决小结

    1:前言 做软件开发这几年遇到了许多的问题,也总结了一些问题的解决之道,之后慢慢的再遇到的都是一些重复性的问题了,当然,还有一些自己没有完全弄明白的问题.如果做的事情是重复的,遇到重复性问题的概率也就 ...

  5. CDH5.16.1的maven依赖版本查询地址

    1查询官网地址,提供了详细的各个版本的jar依赖版本信息 https://www.cloudera.com/documentation/enterprise/release-notes/topics/ ...

  6. .Net版本依赖之坑引发的搜查

    前言 今天上午,一个客户反馈XX消息没有推送到第三方链接.于是我查看了推送日志列表,并没有今天的.接着登录服务器查询文件日志,看到了记录.我们的代码步骤是消息先推送到消息队列,消费消息队列时,记录文件 ...

  7. 查看Eclipse版本号的方法及各个版本区别 Eclipse选择标准

    这篇文章主要介绍了查看Eclipse版本号的方法及各个版本区别 Eclipse选择标准,方便初学者选择适合自己的版本,需要的朋友可以参考下 Eclipse 是一个开放源代码的.基于Java的可扩展开发 ...

  8. Error:依赖版本不一致

    在编译unity时发现一个问题:依赖版本不一致 解决方案: 通过nugut管理在已安装项里选中要更新的dll文件

  9. Springcloud的版本依赖问题(最全,包含springCloud所有的版本)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_42105629/article/detai ...

随机推荐

  1. python之数据驱动ddt操作(方法二)

    import unittestfrom ddt import ddt,unpack,datafrom selenium import webdriverfrom selenium.webdriver. ...

  2. Docker的学习体验

    由于兴致使然,便想学习一点Docker技术.于是,写了这篇学习Docker的体会.笔拙,见谅. 第一件事--把网线插上 相信很多人都被官网的<Sample application>的 do ...

  3. MySQL问题定位-性能优化之我见

    前言 首先任何一个数据库不是独立存在的,也不是凭空想象决定出来的. 数据库的架构离不开应用的场景.所以,为了解决某些深入的问题,首先你得掌握数据库的原理与架构.原理掌握得越深入,越能帮助你定位复杂与隐 ...

  4. Skywalking-03:Skywalking本地调试

    live-demo 与 skywalking 源码联调 构建项目 找一个目录执行如下命令 git clone https://github.com/apache/skywalking.git # cl ...

  5. 将base64Url对应图片保存到本地

    上图中的内容就是base64编码之后对应的Url  图中base64,之前的都是用于声明该图片的格式以及它的编码格式  base64,之后的就是该图片对应的数据了 我们只需要把数据转换为字节保存下来即 ...

  6. Python自动化测试面试题-Linux篇

    目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...

  7. 第十四篇 -- QMainWindow与QAction(清空-全选-撤销-重做-关闭-语言选择)

    效果图: 这次添加了关闭-撤销-重做-全选-清空等功能,并添加了字体和字体大小选择.基本方法跟前面几篇类似. ui_mainWindow.py # -*- coding: utf-8 -*- # Fo ...

  8. redis的过期删除策略

    一.redis的三种过期策略 1.定时删除在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除优点:保证内存被尽快释放缺点:1)若过期key很多, ...

  9. xmind8-update9 安装破解激活教程

    xmind8是一款原型图设计流行的软件,相比于xmind2020功能更为丰富,比如画甘特图等.本教程来教大家如何对xmind8 update9进行安装激活,使用全部功能,无限期使用! 只看本文一篇即可 ...

  10. Android系统编程入门系列之加载服务Service

    之前几篇文章简单梳理了在Android系统的四大组件之一,最主要的界面Activity中,使应用程序与用户进行交互响应的相关知识点,那对于应用程序中不需要与用户交互的逻辑,又要用到哪些内容呢?本文开始 ...