06|构建模式:Go是怎么解决包依赖管理问题的?
该思维导图由 AI 生成,仅供参考
Go 构建模式是怎么演化的?
- 深入了解
- 翻译
- 解释
- 总结
Go Module构建模式是Go语言包依赖管理的重要发展趋势。文章深入探讨了Go Module的语义导入版本机制和最小版本选择原则,强调了Go Module构建模式的创新性和重要性。通过语义版本规范,Go命令可以确定版本发布的先后次序和兼容性,同时Go Module的最小版本选择原则为项目选择符合整体要求的“最小版本”,提供了持久和可重现的构建方案。此外,文章还介绍了Go各版本构建模式机制和切换,帮助读者更好地理解不同版本下、不同构建模式下的行为特性。文章还提到了Go 1.11版本中,Go核心团队推出了新一代构建模式:Go Module以及一系列创新机制,包括语义导入版本机制、最小版本选择机制等。Go Module构建模式将成为Go语言唯一的标准构建模式。
《Tony Bai · Go 语言第一课》,新⼈⾸单¥59
全部留言(69)
- 最新
- 精选
- 张诚目前网上讲包管理讲得最清晰最全面的内容了。
作者回复: 过奖了:)
2021-10-25775 - 若水清菡之前看过两个老师讲go,上来基本上都适合先语法规则后实践的路线,每次go build都一脸懵逼,看下来还是不了解go的编译过程~~~~tony bai老师讲的非常好,遇到一位合适自己的老师,希望跟着学完这门课程,非常感谢老师~
作者回复: 嗯嗯,这次的思路是先让大家上手。但作为入门课,后续必然也会对Go语法进行讲解与深入理解的。
2021-11-14218 - lesserror感谢 Tony Bai 老师的分享,每篇文章我都认真拜读了。 本着持续精进的目的,每篇文章我都会提出一些自己的疑问,麻烦老师抽空解答一下。 1. 在$GOPATH模式下,寻找第三方包依赖的顺序是不是:先找 $GOROOT 然后找 $GOPATH。 2. go.sum文件的工作原理后面能否详细讲讲吗? 感觉这里的讲解还是简单带过了。 3. 文中说:“Go 团队认为“最小版本选择”为 Go 程序实现持久的和可重现的构建提供了最佳的方案。” 这句话能展开讲讲吗? 感觉没明白其中的意思。 4. 第4讲说到:“Go 支持在一个项目 / 仓库中存在多个 module,但这种管理方式可能要比一定比例的代码重复引入更多的复杂性。” 如果项目中引入了第三方 module,比如这篇文章中也引入了第三方 module,这种情况属于 : "在一个项目 / 仓库中存在多个 module" 的情况吗?
作者回复: 你的提问就是对专栏最好的支持,手工点赞! 下面回答你的问题: 1. 从gopath模式下,go build命令的输出来看,是这样的。 2. go.sum机制对于大多数开发人员都是透明的,属于高级话题。因此,在我的这个以入门和基础为重的专栏中并未深入展开。后>续我可能会在自己的博客或公号上谈谈go.sum机制,到时候,你可以去看看。 3. 相较于选择最新最大版本,选择最小版本出于几个考虑吧: 1)对开发者而言,更易于理解和预测,就像课程中例子那样,我们根据依赖图可以很容易确定程序构建最终使用的依赖版本。 2) 对go核心团队来说,更容易实现,据说实现最小选择的代码也就几十行。 3) 更重要的是最小版本选择更容易实现可重现构建。试想一下,如果选择的是最大最新版本,那么针对同一份代码,其依赖包的最新最大版本在不同时刻可能是不同的,那么在不同时刻的构建,产生的最终文件就是不同的。 当然这一切的前提都是基于语义版本规范,对于不符合规范的module,相当于没有遵守契约,这套规则也就失效。这对任何语言来 说都是一样的。 4. 不属于。04讲说的那种情况是指在一个项目仓库中的不同目录下放置了多个go.mod,即一个项目中有多个module。
2021-10-25318 - flexiver老师,您好。想要请问解答两个问题: 1、请问在构建module时, go mod init -module path, 这个module path 是固定要写成github.com/module name这样一个结构吗?
作者回复: 好问题!不必要非得是github.com,也不必要非得是github.com/module name这样的。你可以使用module demo1这样的path。不过module path有三个作用,根据需要作出path的选择: 1. 定位代码仓库位置。如果你的代码是开源到一些公共代码托管站点,或者在组织内部的代码仓库时,path中要带上仓库的地址,比如github.com/repo/module,这样依赖你的module的其他代码可以找到你的module代码。 2. 如果你的module不在repo的根路径下,那么在module path中还要包含子目录路径。以github.com/etcd-io/etcd这个仓库为例。这个仓库下管理着多个go module。以其子目录raft下面的module为例,这个module的path为:module go.etcd.io/etcd/raft/v3。其中的raft就是子路径。 3. major版本号。如果major>=2,需要在module path中加上major号后缀。就像上面的module go.etcd.io/etcd/raft/v3。
2022-03-13413 - 丶能提问! “选择符合项目整体要求的最小版本”是可能选择,依赖最小版本与最新版本中任意版本,还是项目引入版本中的可选范围内的最小版本呢?
作者回复: 按照课程中的例子,A 要求 >=C v1.1.0,B 要求 C >=v1.3.0,那么选择同时满足A与B要求的最小版本,就是v1.3.0。如果选择v1.1.0则不满足A要求。
2021-10-251112 - 太匆匆默认是是最小版本原则,能否修改默认呢?比如举例当中的v1.1.0、v1.3.0、v1.7.0默认会选v1.3.0,开发者能否将其改成v1.7.0呢?
作者回复: 好问题!可以通过go get xxx@v1.7.0显式更新go.mod中的依赖版本。或通过go mod edit命令或直接编辑go.mod进行。
2022-03-23211 - 独钓寒江老师你好,最近 log4j 和 logback 都被发现了安全漏洞,很多Java程序都受到影响,修复起来工作量也不小。如果类似情况出现在Go方面,例如 logrus 出了安全漏洞,我们需要修改依赖版本, 我们可以怎么应对呢?可以简单说说吗?
作者回复: 你这个问题很"与时俱进"啊:)。首先对于已经依赖logrus的版本的go项目,go build不会自动更新logrus到其最新版本,也就不会受到故意漏洞的侵害。假设你的项目在go mod init时获取到的是最新漏洞版本或通过go get logrus@latest获取到其漏洞版本,那么可以看一下07讲,将版本降级或升级到漏洞修复后的版本,操作步骤专栏里都有的。
2021-12-2537 - 李亮关于依赖管理的文档在这里:https://go.dev/doc/modules/managing-dependencies
作者回复: 👍
2022-11-01归属地:北京5 - ゝ骑着小车去兜风。之前做过一个go的项目,用的iris框架,然而拉下来的包始终没有我需要的那个方法,纠结了好久都没办法解决。 现在终于知道是iris框架更新了,导致主板本号不同,需要的那个方法也变成另一个方法了。
作者回复: 👍
2022-04-3045 - 每天晒白牙老师,请教个问题,我是go1.16.4版本,按照老师在文中所说,GO111MODULE 应该为on呀,而我的确实空 (base) ➜ ~ go env GO111MODULE="" GOARCH="amd64" .... GOVERSION="go1.16.4"
作者回复: 所谓默认为on是指,如果GO111MODULE没有显式设置,那么默认为on。你这里环境变量GO111MODULE为空,那么go编译器默认GO111module为on。
2022-05-1024