你期望 Go 1.18 中泛型是什么样子?
前段时间 Rob Pike 在 Go repo 提了一个 issue:go: don't change the libraries in 1.18[1],提到因为泛型是语言层面的大改动,必须循序渐进,步子不能迈太大。具体介绍可以查看:Go 重视兼容性是认真的:泛型得慢慢加。
昨天,Go Team Leader Russ Cox 在 golang-dev 邮件组发了一篇较长的邮件:expectations for generics in Go 1.18[2],对 Go 1.18 与泛型当前进展及后续的支持策略做了说明,已确定 Go 核心团队与社区的努力方向。
以下是该邮件的内容,非完全翻译版。
如果不出严重意外的话,Go 1.18 将包含对泛型的支持。泛型是自 Go1 发布以来最重要的变化,当然也是我们做过的最大一次语言变化[3]。这封邮件解释了包含泛型对我们和用户的意。
任何新的 Go 特性,无论是语言层面还是库层面,都带有不确定性:包括不确定如何使用它,不确定如何不使用它,以及关于哪些微小 bug 已经通过现有测试的不确定性。泛型的加入当然也会存在这种不确定性。事实上,由于泛型是一个较大的新特性,因此不确定性也相应地更大。
因为我们不知道使用泛型的最佳实践是什么,我们的文档将无法给出关于何时使用它们以及何时不使用它们的准确、明确的答案。当然,我们可以而且仍然会给出粗略的泛型使用指南。其实,我们之前也有类似的做法:我们在不间断地编写 Go 代码一整年之后,才写出了 Effective Go 的初始版本[4]。我们对泛型同样没有高水平的经验,因此,虽然我们会提供有关如何使用泛型的文档,但我们无法提供任何关于代码风格和最佳实践的说明。
因为我们不知道编写泛型包的最佳实践是什么,因此,原本计划发布的特意为泛型增加的包 maps 和 slices,不会进入标准库,而是先放入 golang.org/x/exp[5],这里的代码不保证向后兼容。一旦我们有了更多的经验,我们希望将其中一些包加入到标准库中。不过,constraints 包会如期进入 Go1.18 的标准库中,因为它是编写某些泛型代码的基础。
因为我们没有 Go 泛型的任何线上使用经验,所以我们将在发行说明中明确指出,应适当谨慎地处理泛型的生产用途(注:大概率大家也会比较谨慎,不会立马使用)。注意,这不是说团队的工作不出色。毕竟,泛型与大多数 Go 更改不同。当时,我们重写垃圾收集器或更改调用规约时,我们会使用新的实现在测试和生产中运行所有 Google 的 Go 程序,这样就能很好地验证了变化,发现难以发现的错误。相比之下,还在开发的 Go 1.18 工具链重建非泛型代码并不能验证对泛型的支持,这意味着我们无法建立同样的信心。
综上所述,Go 1.18 具有与其他 Go 1.x 版本相同的向后兼容性承诺:我们不会破坏使用 Go 1.18 构建的代码,包括使用泛型的代码。在最坏的情况下,如果我们发现 Go 1.18 语义存在一些致命问题并需要更改它们(例如在 Go 1.19 中),我们将使用 go.mod 文件的 go 版本指示来确定该 module 中的源文件是期望 Go 1.18 还是 Go 1.19+ 语义。(目前,我们预计不需要这样做!)
我们预计一些第三方包的作者会第一时间采用泛型。如果你正在更新你的包以使用泛型,请考虑将新的泛型 API 单独到它自己的文件中,并增加 Go1.18 的构建 tag,如 //go:build go1.18
,以便 Go 1.17 用户可以继续构建和使用非泛型。
另外值得注意的是,第三方工具在 Go 1.18 版本发布时可能不完全支持泛型。我们正在与许多工具的作者交流,并试图确保他们得到适当的更新,但每个工具都会有自己的时间表。
有不少人给我们反馈了一个常见问题:考虑到所有这些不确定性,为什么不让泛型在 Go1.18 中成为可选的?(注:实际上,Go1.17 就有部分可选了)实际上,在这一点上,减少不确定性的唯一方法是默认情况下提供泛型。当我们在 Go 1.5 中可选地加入 vendoring 时,结果真实情况是几乎没有人真正使用它,直到 Go 1.6 默认打开它,大家才使用它。所以 Go 1.5 版本没有减少我们对 Go 开发者使用 vendoring 情况的不确定性。另一方面,这种情况,Go 1.5 版本无疑将生态系统分为“在标准 Go 下运行的代码”和“在启用 vendoring 后运行的代码”两个部分。我们希望 Go1.18 尽可能地避免这种结果。
作为 Go 爱好者,作为期待泛型的你,最重要的事情是编写一些泛型代码,如果你发现了 bug、不清楚的编译器错误等,请提 issue。我最近写了一些泛型数据结构,对整体体验非常满意。我希望你也是;如果没有这种感觉,请提交 issue。谢谢!
by Russ Cox
看完 Russ Cox 的邮件,你对 Go1.18 泛型的情况有了更多了解吧?!
参考资料
go: don't change the libraries in 1.18: https://github.com/golang/go/issues/48918
[2]expectations for generics in Go 1.18: https://groups.google.com/g/golang-dev/c/iuB22_G9Kbo
[3]语言变化: https://tip.golang.org/ref/spec
[4]Effective Go 的初始版本: https://tip.golang.org/doc/effective_go
[5]golang.org/x/exp: https://github.com/golang/exp
推荐阅读