17611538698
webmaster@21cto.com

让Go 1.21 保持『无聊』,Google 工程师谈如何实现向后兼容性

编程语言 2 1194 2023-08-19 03:58:30



Google 工程师Russ Cox 最近详细介绍了 Google 所做的工作,如何确保每个新的 Go 版本都遵循 Go 的向后兼容性保证。


这里包括GODEBUG在 Go 1.21 中进行泛化,以涵盖甚至微妙的不兼容情况。


(原文地址:https://go.dev/blog/compat)


Go 语言的向后兼容性保证是在 Go 1 中引入的,它可以确保所有正确的 Go 程序继续与该语言的未来版本无修改即可使用。Cox 详细解释说,这个目标包含两项主要工作:检查每个 API 更改是否会破坏任何内容,第二进行广泛的测试捕获更微妙的不兼容情况。


虽然检查 API 更改以防止任何重大更改进入新版本的想法,可能听起来很明显,但 Cox 还描述了许多测试和可行性方法的详细情况:


发现意外不兼容性的有效方法是针对下一个 Go 版本的开发版运行现有测试。团队针对 Google 的所有内部 Go 代码滚动测试 Go 的开发版本。当测试通过时,我们将它提交为 Google 的生产安装版本 Go 工具链。


Cox 提供的示例分为几个不同的类别,包括更改time.Now()库函数的精度、输出或输入更改以及协议更改。不过在某些情况下,重大变化是由须纳入该语言重要新功能带来的,例如Go 1.6 中的 HTTP/2 支持、在 Go 1.18 中的 SHA1 功能和相关函数被弃用。


为了处理这种情况,Go 在 1.6 版本中提供了一个特定的功能,即GODEBUG环境变量,可用于禁用特定模块的 HTTP/2。Cox 表示,在 Go 1.21 中,该GODEBUG机制得到了扩展与正式化。


Go 1.21 不使用环境变量,而是使用go:debug,这包含在main包中. 这与模块文件中列出的 Go 版本结合使用go.mod是相同的,这样也方便每个指定的 Go 版本都将具有默认行为,从而确保逐个功能的兼容性,同时go:debug可用于覆盖它。例如,考虑到 Go 1.21 改变了panic(nil)行为,开发人员可能希望将其工具链升级到 Go 1.21,但仍可保留旧版本的行为。go:debug这可以通过使用以下命令覆盖特定于版本的设置:



//go:debug panicnil=1 


根据 Cox 的说法,以上机制使得 Go 的每个新版本都成为旧版本的最佳实现,即使面对重要的重大更改,也可以修复错误,同时也保持了向后兼容性。



作者:万能的大雄

评论