本文翻译自《Go 1 and the Future of Go Programs》。
目录
介绍
期望
子存储库
操作系统
工具
介绍
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规范试图明确该语言的大多数属性,但某些方面未定义。依赖于这种未指定行为的程序可能会在未来的版本中中断运行。
- 规范错误。如果有必要解决规范中的不一致或不完整问题,解决该问题可能会影响现有程序的意义或合法性。我们保留解决此类问题的权利,包括更新实现。除安全问题外,不会对规范进行不兼容的更改。
- Bug。如果编译器或库存在违反规范的Bug,则如果修复了Bug,则依赖于该Bug行为的程序可能会中断运行。我们保留修复此类Bug的权利。
- 结构体字面量。为了在以后的版本中添加功能,可能需要在API中向导出的结构体添加字段。使用无键结构体字面量(例如pkg.T{3, “x”})来创建这些类型的值的代码在此类更改后将无法编译。但是,使用键控结构体字面量(pkg.T{A: 3, B: “x”}) 的代码将在此类更改后继续编译通过。我们将以允许键控结构体字面量保持兼容的方式更新此类数据结构,尽管非键控结构体字面量可能无法编译通过。(还有更复杂的情况涉及嵌套的数据结构或接口,但它们具有相同的解决方法。)因此,我们建议其类型在单独的包中定义的复合文字应使用键控表示法。
- 方法。与结构体字段一样,可能需要向类型添加方法。在某些情况下,例如当该类型与另一种类型一起嵌入到结构中时,添加新方法可能会通过与其他嵌入类型的现有方法产生冲突来破坏结构。我们无法防范这种罕见的情况,也不保证出现这种情况时的兼容性。
- 点导入。如果程序使用
import . "path"
导入标准包,未来版本中导入包中定义的其他名称可能与程序中定义的其他名称冲突。在测试之外,我们不建议使import . "path"
,使用它可能会导致程序在未来的版本中无法编译通过。 - 使用
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树(main go tree)的子存储库中的代码,例如golang.org/x/net,可能会在更宽松的兼容性要求下开发。但是,子存储库将被适当地打标签以识别与Go 1点版本兼容的版本。
操作系统
无法保证与外部各方更改的操作系统接口的长期兼容性。因此,syscall
包不在此处所做保证的范围内。从Go 1.4版本开始,syscall
包被冻结。系统调用接口的任何演变都必须在其他地方得到支持,例如在go.sys子存储库中。有关详细信息和背景,请参阅此文档。
工具
最后,Go工具链(编译器、链接器、构建工具等)正在积极开发中,可能会改变行为。这意味着,例如,依赖于工具位置和属性的脚本可能会被单点发布版本破坏。
除了这些注意事项,我们相信Go 1将成为Go及其生态系统发展的坚实基础。