Go 博客

Go 2,我们来了!

Robert Griesemer
2018年11月29日

背景

在 2017 年的 GopherCon 上,Russ Cox 在他的演讲《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 提案的未解决问题。它们中的每一个都提出了一个重大的库或语言更改,通常是不满足现有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,我们就无法实施该提案。例如,我们认为某种形式的泛型可能会解决许多人的重要问题,但我们还没有清晰且易于理解的解决方案。没关系,这仅仅意味着该提案需要回到绘图板上才能被考虑。

提案

我们认为这是一个良好的计划,应该能很好地为我们服务,但重要的是要理解这只是一个起点。随着流程的使用,我们将发现它在哪些方面无法正常工作,并根据需要对其进行改进。关键之处在于,除非我们在实践中使用它,否则我们不知道如何改进它。

一个安全的起点是使用少量向后兼容的语言提案。我们很长时间没有进行语言更改了,所以这让我们重新回到了这种模式。此外,这些更改不需要我们担心破坏现有代码,因此它们可以作为完美的试飞气球。

综上所述,我们建议将以下 Go 2 提案选入 Go 1.13 版本(提案评估流程中的步骤 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月)中,我们将实现并提供选定的功能,并在代码库的最新版本中提供。每个人都将有机会体验这些功能。这将为反馈提供另一个机会(流程中的步骤4)。

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

(由于存在功能可能在代码库冻结时需要移除的可能性,因此实现需要能够在不破坏系统其余部分稳定的情况下禁用该功能。对于语言更改,这可能意味着所有与功能相关的代码都受内部标志控制。)

这将是我们第一次遵循此流程,因此代码库冻结也将是反思流程并在必要时调整流程的好时机。让我们拭目以待。

祝您评估愉快!

下一篇文章:2019 年的 Go 模块
上一篇文章:Go 的九年历程
博客索引