卓越飞翔博客卓越飞翔博客

卓越飞翔 - 您值得收藏的技术分享站
技术文章34454本站已运行393

使用什么版本的 Go 来编译依赖项?

使用什么版本的 go 来编译依赖项?

php小编百草为您解答使用什么版本的Go来编译依赖项的问题。编译Go代码时,依赖项版本的选择是至关重要的。通常建议使用与项目中已知稳定运行的Go版本兼容的依赖项版本。这样可以确保代码的稳定性和兼容性。同时,也要考虑所使用的依赖项是否还在维护中,是否有与最新版本的Go兼容的更新。综合考虑项目需求和依赖项的特性,选择合适的Go版本来编译依赖项,可以最大程度地保证项目的稳定运行。

问题内容

编译 Go 程序时,是否使用相同版本的 Go 来编译主代码以及依赖代码?

解决方法

这是一个有趣的问题,并且有一个有点微妙的答案。

对于旧版本的 Go,答案很简单:每个依赖项都是使用您本地运行的 Go 版本进行编译的。如果您运行的是 Go 1.9,并且有为 Go 1.10 构建的依赖项,编译器将不会明智地尝试使用 Go 1.9 编译 Go 1.10 代码。只要该依赖项中没有使用新功能,一切都会正常工作。同样,如果您有一个为 Go 1.8 编写的依赖项,它也将使用 Go 1.9 进行编译。

但是,对于现代版本的 Go 以及使用 go.mod 文件的任何项目(或依赖项),行为是不同的。从 Go 模块参考中我们了解到:

  • 对于模块内的包,编译器拒绝使用 go 指令指定的版本之后引入的语言功能。例如,如果模块具有指令 go 1.12,则其包可能不会使用 Go 1.13 中引入的数字文字,例如 1_000_000。

这意味着您的依赖项将仅使用其声明的 Go 版本中提供的功能。然而,它们仍然是使用现代 Go 运行时构建的。因此,在您的 Go 版本中发现的任何性能增强、安全性改进等(比依赖项声明的版本更新)仍然会被使用。

此外,同一文档的下一行说:

  • 如果较旧的 Go 版本构建模块的某个包并遇到编译错误,该错误会指出该模块是为较新的 Go 版本编写的。例如,假设模块的版本为 1.13,而包使用数字文字 1_000_000。如果该包是使用 Go 1.12 构建的,编译器会指出该代码是为 Go 1.13 编写的。

因此,这意味着,如果您尝试使用 Go 1.19 构建程序,并且其中一个依赖项声明版本为 1.20,并且存在编译错误,则编译器输出将通知您潜在的兼容性问题。如果没有编译错误,您可能永远不会注意到差异(因为可能声明 1.20 的依赖项实际上并未使用任何新的 1.20 编译器功能)。

这将比以前产生更明显的影响,可能在 Go 1.22 中,假设 更少容易出错的循环变量作用域提案被及时接受并实施。由于该提案将改变以非向后兼容的方式处理循环变量的方式。假设这确实进入了 Go 1.22,这意味着任何声明 go 1.21 或更早版本的模块都将使用旧的循环语义,任何声明 go 1.22 或更高版本的模块都将使用新的循环语义。这将是 Go 首次违反其向后兼容性承诺,尽管可以说是有充分理由的(因为这个循环变量的事情几乎让每个人都陷入困境)。

卓越飞翔博客
上一篇: 如何在 golang 的 go.mod 中正确使用递归替换?
下一篇: 返回列表
留言与评论(共有 0 条评论)
   
验证码:
隐藏边栏