泛型的下一步
引言
距离我们上次编写向 Go 添加泛型的可行性(https://blog.golang.org/why-generics)已经过去差不多一年了。现在是时候进行更新了。
设计更新
我们一直在不断完善泛型设计草案(https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-contracts.md)。我们已经为它编写了一个类型检查器:一个可以按照设计草案解析使用泛型代码并报告任何类型错误的程序。我们已经完成了示例代码。同时,我们也收集了许许多多人的反馈ーー谢谢你们提供了这些反馈!
基于我们得到的反馈,我们发布一个更新的设计草案(https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md)。最大的变化是我们放弃了contracts
的概念。contracts
和interface
类型之间的差异令人困惑,因此我们尝试消除这种差异。类型参数现在可以被接口类型的约束。现在允许接口类型包含类型列表,但只有在用作约束时才可以。在以前的设计草案中,类型列表是contracts
的一个特性。更复杂的情况将使用参数化的接口类型。
我们希望人们会发现这个设计草案更加简单易懂。
实验性工具
为了帮助确定如何进一步完善设计草案,我们发布了一个翻译工具。这个工具允许开发人员检查和运行使用设计草案的泛型版本开发的代码。它通过将泛型代码转换为普通 Go 代码工作。这个翻译过程有一些局限性,但我们希望它能够让人们对 Go 泛型代码样式有所了解。如果这个设计被接受,泛型的真正实现将会有不同的工作方式。(我们才刚刚开始勾勒出直接编译器实现的大概样子。)
这个工具可以在 https://go2goplay.golang.org 的 Go Playground 上使用。这个 Playground 就像通常的 Go Playground 一样,不过它支持泛型代码。
您也可以自己构建和使用该工具。它在主 Go 仓库中的一个分支中。按照从源代码开始安装 Go 的说明(https://golang.org/doc/install/source)进行操作。不过这些操作说明需要你检查最新的 release 标记,而这里我们需要运行git checkout dev.go2go
。然后按照指引构建 Go 工具链即可。
这个翻译工具在 README.go2go (https://go.googlesource.com/go/+/refs/heads/dev.go2go/README.go2go.md)中有文档说明。
下一步
我们希望这个工具能给 Go 社区一个体验泛型的机会。我们希望通过这个工具了解两件事情。
首先,泛型代码有意义吗?感觉像 Go 的风格吗?人们会遇到什么样的惊喜?错误消息有用吗?
其次,我们知道很多人说 Go 需要泛型,但是我们不一定知道泛型使用具体是什么样的场景。这个设计草案是否有效地解决了问题?如果有一个问题使你认为 “如果 Go 有泛型,我就可以解决这个问题” ,那么在使用这个工具能解决你的问题吗?
我们将使用从 Go 社区中收集到的反馈来决定如何前进。如果设计草案很受欢迎,并且不需要重大修改,那么下一步这将是一个正式的语言变更提案(https://github.com/golang/proposal#readme)。为了设定预期,如果所有人都对设计草案完全满意,并且不需要进一步的调整,那么最早泛型将会 2021 年 8 月发布的 Go 1.17 进行添加。当然,在现实中,可能会有不可预见的问题,所以这是一个乐观的时间表; 我们不能作出任何明确的预测。
反馈
提供语言变化反馈的最好方法是在邮件列表 golang-nuts@googlegroups.com 上。邮件列表并不是完美的,但它们似乎是我们早期讨论的最佳选择。在撰写设计草案时,请将[generics]
放在主题行的开头,并针对不同的具体主题使用不同的讨论串。
如果你在泛型类型检查器或者翻译工具中发现了 bug,它们应该被提交到 Go 问题追踪 https://golang.org/issue 中。请以 cmd/go2go:.
作为标题的开头。注意,问题追踪不是讨论语言更改的最佳位置,因为它不提供讨论串,也不适合长时间的对话。
我们期待着你的反馈。
致谢
我们还没有结束,但是我们已经走了很长的路。如果没有很多的帮助,我们无法到达这里。
我们要感谢 Philip Wadler 和他的合作者,他们正式地思考了 Go 中的泛型,并帮助我们厘清了设计的理论方面。他们的论文 Featherweight Go (https://arxiv.org/abs/2005.11710)在受限的 Go 版本中分析泛型,并且他们在 GitHub 上开发了一个原型。
我们还要感谢那些对早期版本的设计草案提供了详细反馈的人。
最后但却很重要的一点就是,我们要感谢 Go 团队的许多人,Go 问题追踪的许多贡献者,以及所有其他对早期设计草案分享想法和反馈的人(https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#acknowledgements)。我们读完了所有的文章,我们很感激。没有你我们不会到达这里。
点击“阅读原文”即可查看:The Next Step for Generics