Go 官方发博文,宣布 Go 泛型 草案更新,最早将在 Go1.17 中加入泛型,也就是明年的 8 月份。一起来看下具体内容。
介绍
自我们上次撰写关于在 Go 中添加泛型 已经快一年[1] 了。现在该进行更新了。
更新设计
我们一直在不断完善 泛型设计草案[2] 。我们为此编写了一个类型检查器:一个程序,可以按照设计草案中的说明解析使用了泛型的 Go 代码并报告任何类型错误。我们已经编写了示例代码。而且我们已经收集了许多人的反馈—感谢您提供!
根据反馈和掌握的知识,我们发布了 更新的设计草案[3] 。最大的变化是我们放弃了 contracts 的想法。contracts 和 interface 类型之间的区别令人困惑,因此我们消除了这种区别。类型参数现在受接口类型的约束。现在当仅作为约束时,接口类型可以包含类型列表。在以前的设计草案中,类型列表是 contracts 的功能。更复杂的情况将使用参数化的接口类型。
我们希望人们会发现该设计草案更简单易懂。
实验工具
为了帮助决定如何进一步完善设计草案,我们发布了翻译工具。这是一个会进行类型检查并运行使用设计草案中描述的泛型版本编写代码的工具。它通过将泛型代码转换为普通的 Go 代码来工作。这个翻译过程有一定的局限性,但是我们希望它对 Gopher 来说足以使他们对反泛型 Go 代码的整体有所了解。如果该泛型被接受,它们的实际实现可能有所不同。(我们才刚刚开始勾勒出直接编译器实现的情况。)
可以在 上的 Go playground 的变体上使用该工具。这个 playground 的工作方式与通常的 Go playground 相同,但是它支持泛型代码。
您也可以自己构建和使用该工具。它可以在 Go 主仓库的分支中找到。按照有关 从源安装 Go[4] 的说明进行操作。这些说明指导您检出最新的发行版标签,然后运行 git checkout dev.go2go,接着按照指示构建 Go 工具链。
翻译工具记录在 README.go2go[5] 中。
下一步
我们希望该工具将使 Go 社区有机会尝试使用泛型。我们希望了解两件事。
首先,泛型代码有意义吗?感觉像 Go 吗?人们会遇到什么惊喜?错误消息有用吗?
其次,我们知道很多人都说 Go 需要泛型,但是我们不一定确切知道这意味着什么。该设计草案是否以有用的方式解决了该问题?如果有一个问题使您认为“如果 Go 具有泛型,我可以解决此问题”,那么使用此工具可以解决问题吗?
我们将使用从 Go 社区收集的反馈来决定如何推进。如果设计草案很受欢迎,并且不需要进行重大更改,那么下一步将是 正式的语言更改建议[6] 。为了保证符合预期,如果每个人都对设计草案完全满意并且不需要任何进一步的调整,那么最早可以在 Go 中添加泛型的便是计划于 2021 年 8 月发布的 Go 1.17 版本。可能存在无法预料的问题,所以这是一个乐观的时间表;我们无法做出任何明确的预测。
反馈
提供有关语言更改的反馈的最佳方法是在邮件列表 golang-nuts@googlegroups.com 上。邮件列表并不完美,但它们似乎是我们进行初始讨论的最佳选择。在撰写设计草案时,请在主题行的开头放置[generics],并针对不同的特定主题启动相应的主题。
如果您在泛型类型检查器或翻译工具中发现 bug,则应将其提交到标准 Go issue 跟踪器中,网址为 https:// GitHub .com/golang/go/issues。请以 cmd/go2go: 作为 issue 的标题开头。请注意,issue 跟踪器不是讨论语言更改的最佳场所,因为它不提供线索并且也不适合长时间的对话。
我们期待您的反馈。
致谢
我们还没有完成,但是已经走了很长一段路。如果没有很多帮助,我们不会发展到现在。
我们要感谢 Philip Wadler 及其合作者对 Go 中的泛型形式进行了正式思考,并帮助我们阐明了设计的理论方面。他们的论文 Featherweight Go[7] 分析了 Go 受限版本中的泛型,并在 GitHub[8] 上开发了一个原型。
我们还要感谢那些对设计草案的早期版本提供详细反馈的 人员[9] 。
最后但并非最不重要的一点是,我们要感谢 Go 团队中的许多人,Go issue 跟踪器的许多贡献者以及其他对早期设计草案分享想法和反馈的人。我们阅读了所有内容,我们非常感谢。没有您,我们不会发展到现在。
参考资料
[1] 已经快一年:
[2] 泛型设计草案:
[3] 更新的设计草案:
[4] 从源安装 Go:
[5] README.go2go:
[6] 正式的语言更改建议:
[7] Featherweight Go:
[8] GitHub:
[9] 人员: #acknowledgements