Go 1和Go程序的未来

Go 1 and the Future of Go Programs - Go 1和Go程序的未来

原文:https://go.dev/doc/go1compat

简介

​ Go 1版本的发布,简称Go 1,是该语言发展的一个重要里程碑。Go 1是一个稳定的平台,有利于用Go编写的程序和项目的发展。

​ Go 1定义了两件事:第一,语言的规范;第二,一组核心API的规范,即Go库的 “标准包”。Go 1的发布包括它们的实现,形式为两个编译器套件(gc和gccgo),以及核心库本身。

​ 我们希望按照 Go 1 规范编写的程序能够在该规范的有效期内继续正确地编译和运行,而不发生变化。在某个不确定的时间点上,可能会出现 Go 2 规范,但在那之前,即使未来出现 Go 1 的 “点 “版本(Go 1.1、Go 1.2 等),今天能运行的 Go 程序也应该继续运行。

​ 兼容性是在源码层面上的。编译后包的二进制兼容性在不同的版本之间不被保证。在发布一个点版本之后,Go源代码需要重新编译以链接到新版本。

​ API可能会增长,获得新的包和功能,但不会破坏现有的Go 1代码。

期望

​ 尽管我们期望绝大多数程序能够随着时间的推移保持这种兼容性,但我们不可能保证未来的变化不会破坏任何程序。本文件试图为Go 1软件在未来的兼容性设定期望。有许多方式可以使今天能编译和运行的程序在未来的一个点发布后无法运行。这些问题都是不太可能的,但值得记录。

  • 安全问题。规范或实现中的安全问题可能会被发现,其解决需要破坏兼容性。我们保留解决这些安全问题的权利。
  • 未指定的行为。Go 规范试图明确说明语言的大多数属性,但也有一些方面是未定义的。依赖于这种未指定行为的程序在未来的版本中可能会出现故障。
  • 规范错误。如果有必要解决规范中的不一致或不完整,解决这个问题可能会影响现有程序的含义或合法性。除了安全问题外,我们保留解决此类问题的权利,包括更新实现。不会对规范进行不兼容的更改。
  • Bugs。如果一个编译器或库有一个违反规范的bug,如果bug被修复,一个依赖于bug行为的程序可能会被破坏。我们保留修复这些错误的权利。
  • 结构体字面量。为了在以后的点版本中增加功能,可能有必要在API中为导出的结构体添加字段。使用未加键的结构字面量(如 pkg.T{3, "x"})来创建这些类型的值的代码,在这种改变之后将无法编译。然而,使用带键字面量的代码(pkg.T{A: 3, B: "x"})在这种变化后将继续编译。我们将更新此类数据结构,使带键的结构字面量保持兼容,尽管未带键的字面量可能无法编译。(还有一些更复杂的情况,涉及嵌套的数据结构体或接口,但它们有相同的解决方法)。因此,我们建议类型被定义在一个单独的包中的复合字面量应该使用带键的表示法。
  • 方法。与结构体字段一样,可能有必要为类型添加方法。在某些情况下,例如当类型与另一个类型一起嵌入到一个结构体中时,新方法的添加可能会与其他嵌入类型的现有方法产生冲突,从而破坏结构体。我们无法防止这种罕见的情况,也不保证在出现这种情况时的兼容性。
  • 点导入。如果一个程序使用 import . "path",在未来的版本中,在导入的包中定义的其他名称可能会与程序中定义的其他名称冲突。我们不推荐在测试之外使用 import .,使用它可能导致程序在未来的版本中无法编译。
  • 使用unsafe包。导入unsafe的包可能依赖于Go实现的内部属性。我们保留对实现进行修改的权利,这可能会破坏此类程序。

​ 当然,对于所有这些可能性,如果它们出现,我们会在可行的情况下努力更新规范、编译器或库,而不影响现有的代码。

​ 这些考虑同样适用于连续的点发布。例如,在Go 1.2下运行的代码应该与Go 1.2.1、Go 1.3、Go 1.4等兼容,但不一定与Go 1.1兼容,因为它可能使用仅在 Go 1.2 中添加的功能。

​ 在两个版本之间增加的功能,在源码库中可用,但不属于编号的二进制版本的一部分,正在积极开发中。在这些功能发布之前,我们不会对使用这些功能的软件做出兼容性的承诺。

​ 最后,尽管这不是一个正确性问题,但一个程序的性能可能会受到它所依赖的编译器或库的实现的变化的影响。对于一个特定程序在不同版本之间的性能,我们无法做出保证。

​ 虽然这些期望适用于Go 1本身,但我们希望在开发基于Go 1的外部开发软件时也能有类似的考虑。

子存储库

​ 主go树的子存储库中的代码,如golang.org/x/net,可以在较宽松的兼容性要求下开发。然而,子存储库将被适当地标记,以确定与 Go 1 点版本兼容的版本。

操作系统

​ 我们不可能保证与操作系统接口的长期兼容性,因为这些接口是由外界改变的。因此,syscall包不在这里的保证范围内。从Go 1.4版本开始,syscall包被冻结。任何系统调用接口的演变都必须在其他地方得到支持,比如go.sys子存储库。详情和背景请见此文档

工具

​ 最后,Go 工具链(编译器、链接器、构建工具等)正在积极开发中,可能会更改行为。这意味着,例如,依赖于工具的位置和属性的脚本可能会被点发布所破坏。

​ 抛开这些注意事项,我们相信Go 1将成为Go及其生态系统发展的坚实基础。

最后修改 October 10, 2024: 更新 (a4b8f85)