Go 博客

Go 2,我们来了!

Robert Griesemer
2018年11月29日

背景

在 2017 年 GopherCon 大会上,Russ Cox 发表了题为《Go 的未来》(The Future of Go博文)的演讲,正式开启了对 Go 下一个重大版本的思考。我们将这个未来的语言非正式地称为 Go 2,尽管我们现在明白它将以增量步骤而非一次性盛大发布的形式到来。尽管如此,Go 2 仍然是一个有用的代号,即使只是为了有一个讨论未来语言的方式,所以我们暂时继续使用它。

Go 1 和 Go 2 之间的一个主要区别在于谁将影响设计以及如何做出决策。Go 1 是一个小型团队的努力,外部影响有限;Go 2 将更多地由社区驱动。经过近 10 年的实践,我们对语言和库有了很多最初未曾想到的了解,而这一切都得益于 Go 社区的反馈。

2015 年,我们推出了提案流程,用于收集一种特定的反馈:语言和库更改的提案。由 Go 核心团队成员组成的委员会定期审查、分类和决定收到的提案。这进行得很顺利,但在该过程中,我们忽略了所有不向后兼容的提案,简单地将它们标记为 Go 2。2017 年,我们还停止了任何形式的增量式向后兼容的语言更改,无论多么微小,而是采取了一个更全面的计划,其中考虑了 Go 2 的整体蓝图。

现在是时候对 Go 2 的提案采取行动了,但要做到这一点,我们首先需要一个计划。

状态

在撰写本文时,有大约 120 个标记为“Go 2 proposal”的开放问题。其中每个提案都提出了重要的库或语言更改,其中许多不满足现有的Go 1 兼容性保证。Ian Lance Taylor 和我一直在审查这些提案,并对其进行了分类(Go2CleanupNeedsDecision 等),以便了解其内容并更容易地进行处理。我们还合并了相关的提案,并关闭了那些明显超出 Go 范围或无法操作的提案。

剩余提案中的想法很可能会影响 Go 2 的库和语言。早期出现了两个主要主题:更好的错误处理支持和泛型。今年 GopherCon 大会上发布了这两个领域的草案设计,还需要进一步的探索。

但其他提案呢?我们受到限制,因为我们现在有数百万 Go 程序员和大量的 Go 代码,我们需要将它们全部带上,以免我们冒着生态系统分裂的风险。这意味着我们不能做太多更改,并且需要仔细选择我们将要进行的更改。为了取得进展,我们将为这些重大的潜在更改实施一个新的提案评估流程。

提案评估流程

提案评估流程的目的是收集对少量精选提案的反馈,以便做出最终决定。该流程与发布周期大致并行运行,并包含以下步骤:

  1. 提案选择。Go 团队选择少量Go 2 提案,这些提案似乎值得考虑接受,但尚未做出最终决定。有关选择标准,请参见下文。

  2. 提案反馈。Go 团队会发布公告,列出选定的提案。公告向社区解释了推进选定提案的初步意图,并征求对每个提案的反馈。这使社区有机会提出建议和表达担忧。

  3. 实现。基于这些反馈,提案将被实现。这些重大的语言和库更改的目标是在即将发布的发布周期的第一天准备就绪。

  4. 实现反馈。在开发周期中,Go 团队和社区有机会试用新功能并收集进一步的反馈。

  5. 发布决策。在三个月的开发周期结束时(就在开始发布前的三个月存储库冻结之前),基于在开发周期中收集的经验和反馈,Go 团队将就是否发布每项更改做出最终决定。这提供了一个机会来考虑更改是否带来了预期的好处或产生了任何意外的成本。一旦发布,这些更改将成为语言和库的一部分。被排除的提案可能会重新审视,或者可能被永久拒绝。

通过两轮反馈,此流程倾向于拒绝提案,这有望防止功能蔓延并有助于保持语言的精简和清晰。

我们无法为每个开放的 Go 2 提案都走这个流程,因为它们的数量实在太多了。这就是选择标准发挥作用的地方。

提案选择标准

提案至少必须

  1. 解决许多人面临的重要问题,

  2. 对其他人造成最小的影响,并且

  3. 提供清晰且易于理解的解决方案.

要求 1 确保我们所做的任何更改都能帮助尽可能多的 Go 开发人员(使他们的代码更健壮、更容易编写、更可能正确等等),而要求 2 确保我们小心地伤害尽可能少的开发人员,无论是通过破坏他们的程序还是引起其他变化。经验法则:对于给定的更改,我们应该旨在帮助的开发人员数量至少是受伤害的开发人员数量的十倍。不影响实际 Go 使用的更改,其净收益为零,并且实施成本很高,应避免。

如果没有要求 3,我们就无法实现提案。例如,我们认为某种形式的泛型可以解决许多人面临的重要问题,但我们还没有清晰且易于理解的解决方案。没关系,这仅仅意味着提案在被考虑之前需要重新审视。

Proposals

我们认为这是一个很好的计划,应该对我们很有帮助,但重要的是要理解这仅仅是一个起点。随着流程的实施,我们将发现它在哪些方面未能良好运作,并将根据需要进行改进。关键在于,直到我们在实践中使用它,我们才不知道如何改进它。

一个安全的起点是采用少数向后兼容的语言提案。我们很长时间没有进行语言更改了,所以这有助于我们重新进入那个状态。此外,这些更改不会让我们担心破坏现有代码,因此它们可以作为完美的试探性方案。

话虽如此,我们建议为 Go 1.13 版本选择以下 Go 2 提案(提案评估流程的步骤 1):

  1. #20706 基于 Unicode TR31 的通用 Unicode 标识符:这解决了使用非西方字母的 Go 程序员面临的一个重要问题,并且对其他人的影响很小甚至没有。存在一些我们需要回答的规范化问题,社区的反馈在此很重要,但在那之后,实现路径是明确的。请注意,标识符导出规则不会受到影响。

  2. #19308, #28493 二进制整数文字以及支持数字文字中的“_”:这些是相对较小的更改,在许多程序员中似乎非常受欢迎。它们可能未能完全达到解决“重要问题”的门槛(十六进制数字到目前为止一直运行良好),但它们使 Go 在这方面与其他大多数语言保持一致,并缓解了一些程序员的痛点。对于那些不关心二进制整数文字或数字格式的其他人,影响很小,并且实现也是明确的。

  3. #19113 允许有符号整数作为移位计数:据估计,所有非常量移位的 38% 需要(人为地)进行 uint 转换(有关更详细的细分,请参阅问题)。此提案将清理大量代码,使移位表达式与索引表达式以及内置函数 cap 和 len 更好地同步。它将主要对代码产生积极影响。实现是明确的。

下一步

通过这篇博文,我们已经执行了第一步,并开始了提案评估流程的第二步。现在,轮到 Go 社区了,请您就上述问题提供反馈。

对于我们收到清晰且赞同反馈的每个提案,我们将继续推进实现(流程的步骤 3)。因为我们希望在下一个发布周期的第一天(暂定为 2019 年 2 月 1 日)实现更改,所以我们可能会提前开始实现,以便留出两个月的完整反馈时间(2018 年 12 月、2019 年 1 月)。

在为期三个月的开发周期(2019 年 2 月至 5 月)中,选定的功能将在 tip 版本中实现并可用,每个人都有机会从中获得经验。这提供了另一个反馈机会(流程的步骤 4)。

最后,在存储库冻结后不久(2019 年 5 月 1 日),Go 团队将做出最终决定,是永久保留新功能(并将其包含在 Go 1 兼容性保证中),还是放弃它们(流程的最后一步)。

(由于一项功能可能需要在存储库冻结时才被移除,因此实现需要能够禁用该功能而不破坏系统的其余部分。对于语言更改,这可能意味着所有与功能相关的代码都由内部标志保护。)

这将是我们第一次遵循此流程,因此存储库冻结也将是反思该流程并根据需要进行调整的好时机。让我们看看进展如何。

评估愉快!

下一篇文章:2019 年 Go Modules
上一篇文章:Go 的九年
博客索引