Go 博客

泛型的下一步

Ian Lance Taylor 和 Robert Griesemer
2020 年 6 月 16 日

介绍

我们已经差不多一年没有写过关于在 Go 中添加泛型的可能性的文章了。现在是更新的时候了。

更新的设计

我们一直在继续改进泛型设计草案。我们已经为它编写了一个类型检查器:一个程序,可以解析使用泛型编写的 Go 代码(如设计草案中所述)并报告任何类型错误。我们已经编写了示例代码。并且我们收集了来自许多人的反馈——感谢您的提供!

根据我们所学到的东西,我们正在发布一个更新的设计草案。最大的变化是我们放弃了契约的想法。契约和接口类型之间的区别令人困惑,因此我们正在消除这种区别。类型参数现在受接口类型的约束。现在允许接口类型包含类型列表,但仅在用作约束时;在之前的设计草案中,类型列表是契约的一个特性。更复杂的情况将使用参数化接口类型。

我们希望人们会发现这个设计草案更简单易懂。

实验工具

为了帮助决定如何进一步改进设计草案,我们正在发布一个翻译工具。这是一个允许人们类型检查和运行使用设计草案中描述的泛型版本编写的代码的工具。它的工作原理是将泛型代码翻译成普通的 Go 代码。这个翻译过程会带来一些限制,但我们希望它足以让人们感受一下泛型 Go 代码可能是什么样的。泛型的真实实现(如果它们被接受到语言中)将以不同的方式工作。(我们才刚刚开始勾勒出直接编译器实现可能是什么样子。)

该工具在 Go playground 的一个变体上可用,地址为https://go2goplay.golang.org。这个 playground 的工作原理与通常的 Go playground 一样,但它支持泛型代码。

您也可以自己构建和使用该工具。它在 master Go repo 的一个分支中可用。按照从源代码安装 Go 的说明进行操作。在这些说明指示您签出最新发布标签的地方,改为运行git checkout dev.go2go。然后按照指示构建 Go 工具链。

该翻译工具在README.go2go中进行了文档说明。

下一步

我们希望该工具能给 Go 社区一个机会去尝试泛型。我们希望了解两件主要的事情。

首先,泛型代码是否有意义?它感觉像是 Go 吗?人们会遇到什么意外?错误消息是否有用?

其次,我们知道许多人说过 Go 需要泛型,但我们不一定确切地知道这意味着什么。这个草案设计是否以一种有用的方式解决了这个问题?如果有问题让你觉得“如果 Go 有泛型,我就可以解决这个问题”,你使用这个工具可以解决这个问题吗?

我们将根据从 Go 社区收集到的反馈来决定如何向前推进。如果草案设计得到了很好的认可并且不需要进行重大更改,下一步将是正式的语言更改提案。为了设定预期,如果每个人都对设计草案完全满意,并且不需要任何进一步调整,那么最早可以在计划于 2021 年 8 月发布的 Go 1.17 版本中添加泛型。当然,实际上可能存在不可预见的问题,因此这是一个乐观的计划;我们无法做出任何确定的预测。

反馈

提供语言更改反馈的最佳方式是在邮件列表[email protected]上。邮件列表并不完美,但它们似乎是我们进行初始讨论的最佳选择。在撰写有关设计草案的文章时,请在主题行的开头加上[generics],并为不同的特定主题启动不同的主题。

如果您在泛型类型检查器或翻译工具中发现错误,则应在标准 Go 问题跟踪器go.dev/issue中提交。请以cmd/go2go:开头您的问题标题。请注意,问题跟踪器不是讨论语言更改的最佳场所,因为它不提供线程,也不适合进行冗长的对话。

我们期待您的反馈。

致谢

我们还没有完成,但我们已经取得了长足的进步。如果没有许多帮助,我们不可能走到今天。

我们要感谢 Philip Wadler 及其合作者,他们在形式上思考 Go 中的泛型,并帮助我们澄清了设计理论方面。他们的论文Featherweight Go分析了 Go 的限制版本中的泛型,并且他们在GitHub上开发了一个原型。

我们还要感谢那些对早期版本的设计草案提供了详细反馈的人。

最后但同样重要的是,我们要感谢 Go 团队的许多人、Go 问题跟踪器的许多贡献者,以及所有在早期设计草案中分享想法和反馈的人。我们阅读了所有内容,并表示感谢。没有你们,我们不可能走到今天。

下一篇文章:保持模块兼容性
上一篇文章:Pkg.go.dev 是开源的!
博客索引