无论何时编译Go程序,编译主代码和依赖代码时使用的是同一版本的Go吗?
idfiyjo81#
是的,依赖项是使用与代码相同的编译器编译的,因此它是相同的版本。Go模块可以在其go.mod中声明minimum version directive,如下所示:
go.mod
module example.com/mymodule go 1.14
这以两种方式影响编译器行为:如果依赖项go.mod中指定的版本比编译器的版本新,它将尝试编译,但如果遇到错误,则会输出一条消息,警告用户该模块已使用较新版本的Go编写。如果依赖项go.mod中指定的版本比编译器的版本旧,则在指定版本之后引入的语言功能将被拒绝。
6yt4nkrj2#
这是一个有趣的问题,并有一个微妙的答案。对于老版本的Go,答案很简单:每个依赖项都是使用您在本地运行的Go版本编译的。如果你正在运行Go 1.9,并且你有为Go 1.10构建的依赖项,编译器将不会更明智,并尝试使用Go 1.9编译Go 1.10代码。只要在该依赖项中没有使用新特性,它就可以正常工作。同样,如果你有一个为Go 1.8构建的依赖项,它也会使用Go 1.9编译。然而,对于现代版本的Go,以及任何使用go.mod文件的项目(或依赖项),行为是不同的。从Go Modules Reference中我们了解到:
这意味着你的依赖项将只使用Go的 * 声明版本 * 中可用的功能。然而,它们仍然是使用现代Go运行时构建的。因此,在您的Go版本中发现的任何性能增强,安全改进等,都比依赖项的声明版本更新,仍然使用。此外,同一文件的下一行说:
所以这意味着如果你试图使用Go 1.19构建一个程序,并且其中一个依赖项声明了版本1.20 * 并且 * 存在编译错误,编译器输出将通知你潜在的兼容性问题。如果没有编译错误,您可能永远不会注意到差异(因为可能声明1.20的依赖项实际上并没有使用任何新的1.20编译器功能)。这将产生比以前更明显的影响,可能在Go 1.22中,假设less error-prone loop variable scoping提案被接受并及时实现。因为这个建议将改变循环变量的处理方式,使其不向后兼容。假设Go 1.22中确实有这个,这意味着任何声明go 1.21或更早版本的模块都将使用旧的循环语义,而任何声明go 1.22或更高版本的模块都将使用新的循环语义。这将是Go语言第一次打破它的向后兼容性承诺,尽管有很好的理由(因为这个循环变量几乎每个人都被绊倒了)。
go 1.21
go 1.22
2条答案
按热度按时间idfiyjo81#
是的,依赖项是使用与代码相同的编译器编译的,因此它是相同的版本。
Go模块可以在其
go.mod
中声明minimum version directive,如下所示:这以两种方式影响编译器行为:
如果依赖项
go.mod
中指定的版本比编译器的版本新,它将尝试编译,但如果遇到错误,则会输出一条消息,警告用户该模块已使用较新版本的Go编写。如果依赖项
go.mod
中指定的版本比编译器的版本旧,则在指定版本之后引入的语言功能将被拒绝。6yt4nkrj2#
这是一个有趣的问题,并有一个微妙的答案。
对于老版本的Go,答案很简单:每个依赖项都是使用您在本地运行的Go版本编译的。如果你正在运行Go 1.9,并且你有为Go 1.10构建的依赖项,编译器将不会更明智,并尝试使用Go 1.9编译Go 1.10代码。只要在该依赖项中没有使用新特性,它就可以正常工作。同样,如果你有一个为Go 1.8构建的依赖项,它也会使用Go 1.9编译。
然而,对于现代版本的Go,以及任何使用
go.mod
文件的项目(或依赖项),行为是不同的。从Go Modules Reference中我们了解到:这意味着你的依赖项将只使用Go的 * 声明版本 * 中可用的功能。然而,它们仍然是使用现代Go运行时构建的。因此,在您的Go版本中发现的任何性能增强,安全改进等,都比依赖项的声明版本更新,仍然使用。
此外,同一文件的下一行说:
所以这意味着如果你试图使用Go 1.19构建一个程序,并且其中一个依赖项声明了版本1.20 * 并且 * 存在编译错误,编译器输出将通知你潜在的兼容性问题。如果没有编译错误,您可能永远不会注意到差异(因为可能声明1.20的依赖项实际上并没有使用任何新的1.20编译器功能)。
这将产生比以前更明显的影响,可能在Go 1.22中,假设less error-prone loop variable scoping提案被接受并及时实现。因为这个建议将改变循环变量的处理方式,使其不向后兼容。假设Go 1.22中确实有这个,这意味着任何声明
go 1.21
或更早版本的模块都将使用旧的循环语义,而任何声明go 1.22
或更高版本的模块都将使用新的循环语义。这将是Go语言第一次打破它的向后兼容性承诺,尽管有很好的理由(因为这个循环变量几乎每个人都被绊倒了)。