今年 8 月 Go 开发团队公布了 Go 2.0
的设计草案,包括错误处理和泛型这两大主题。现在备受瞩目的
Go 2.0 又有了新动向 —— 昨日 Go 开发团队在其官方博客表示,Go 2
已经被安排上了!目前 Go 2
已进入确定变更提案的阶段,并公布了提案评估流程。

Go 2 又有进展了,近日 Go
团队在博客公布了关于 Go 2
下一步的计划。根据此前的报道,所谓的 Go 2
并非一个单独的重大更新版本,而是通过“增量(incremental)更新”的方式以逐渐抵达
“Go 2.0″,所以期间的版本都能看到 Go 2 的影子。

Go 语言作者之一 Robert Griesemer 前几天代表 Go
语言开发团队的提案审查委员会公布了关于否决一项提案的决定。Robert
在「内置的 Go
错误检查函数,”try”」提案下面的回复中发布了这个公告,并表示基于社区压倒性的反应和由此引起的广泛讨论,团队决定提前拒绝此项提案。

废话不多说,先来看看 Go 2.0 有哪些值得关注的内容:

图片 1

图片 2

1.最大程度保持对 1.x 的兼容,以避免分裂 Go 语言生态系统
2.采用增量升级的方式,而非单独发布重大更新版本
3.实施新的提案评估流程,以评估尚未解决且被标记为提案的
issue
4.将会在 Go 1.13 版本中选择 Go 2 部分的提案

当前状态

Go 团队表示正准备推出 Go 1.13,有望在今年 8
月初发布。经历长时间的开发后,这会是首个包括对语言特性进行具体更改的重要版本,而不仅仅是针对规范的小调整。

为了实现这些变化,Go
团队从一小系列可行的提案开始,这些提案很大一部分来自 GitHub
中被标记为提案的 issue
列表。此文讲述过关于提案新的评估流程,团队希望所选择的提案对语言的改动较小,而且几乎没有争议,这样是为了保证经历完全程后,最终能实现这些提案。另外,提案引起的变更必须向后兼容,以实现最小的破坏性。

总而言之,初始阶段的变更不是为了解决重大问题,更多的是希望 Go
社区重新活跃起来,并从新的流程中汲取经验。

对于原始的提案列表 —— 通用 Unicode
标识符、二进制整数字面量(binary
integer
literals)、用于数字字面量的分隔符和 signed
integer shift
counts,官方表示已采纳部分并对它们进行了修改。如关于二进制字面量的提案,团队已对其进行了显著的扩展,并对
Go 的数字字面量语法进行全面和现代化的改进。

Go 团队还将错误处理(error inspection) 添加到了 Go 2
的草案设计提案中,该提案已被部分接受。

在 Go 1.13 中,我们将能看到这些变化,不过官方表示现在关注的重点是 Go
1.14,并确定接下来要解决的问题。

关于 Go 2 的错误处理问题,Robert
表示团队去年就已阐述了对此的看法,但当时并没引起足够的注意和讨论。所以关于”try”语句的提案可能是解决此问题的一个很好的解决方案,但对于大多数使用者而言,这可能没解决到什么问题。

背景

早在2017年的 GopherCon 大会上,Russ Cox(Go 核心开发团队的技术
leader)就已经正式开始思考 Go
的下一个大版本(相关文章)。当时官方非正式地将它称为 Go
2,但我们知道,所谓的 Go
2.0 并非一个单独的重大更新版本,而是通过“增量更新(incremental)”的方式以逐渐抵达
“Go 2.0″。所以本文对这个未来版本的称号 —— 也暂且用 Go 2 来描述。

Go 1 和 Go 2
之间的主要区别在于主导权的不同。谁将影响设计,又该如何做出决策?我们都知道,Go
1 的诞生是小团队努力的结果,受外部影响不大;而到了 Go 2,尤其是经过将近
10 年的发展后,Go
语言的生态已经十分庞大,因此它也更多地受到社区的驱动和影响。经历了这些,Go
开发团队也了解到了更多一开始不知道的与语言特性和库相关的知识 ——
这些都来自于 Go 社区的反馈。

2015年,Go
开发团队引入了提案流程,以收集特定类型的反馈:针对语言和库变更方面的提案。由
Go
开发团队高级成员组成的委员会定期审查、分类和决定社区提交的提案。这个流程十分有效,但作为该过程的一部分,他们忽略了所有不向后兼容的提案,只是将其标记至 Go
2。到了2017年,Go
开发团队也停止进行任何类型的向后兼容的“增量”语言特性变更,因为他们认为无论变更多么小,都要有更全面的支持计划,并将
Go 2 考虑在内。

对于这些累积下来的提案,官方表示现在是时候采取行动了!

关于 Go 1.14 的提案

Go 团队表示当前对 Go
语言的目标依旧和
2007 年的一致:成为一门使软件开发更具伸缩性的语言。在这条路上,改进 Go
伸缩性的三大难题包括:包/版本管理、错误处理以及泛型。

不过随着对 Go module
的支持日益强大,团队正在努力解决对包/版本管理支持的问题。所以现在主要剩下错误处理和泛型的问题亟需解决。

团队一直在研究和它们相关的问题,并在去年的 GopherCon
大会上提出了设计草案。自那时起,团队就一直在迭代和改进这些设计。对于错误处理,他们发布了一个详细的、经过重大修改和简化的草案。对于泛型,团队表示已取得进展,今年还在
GopherCon 上进行了一场名为 “Generics in Go” 的演讲(Ian Lance Taylor
作为演讲者),不过尚未达到具体的提案阶段。

团队希望给 Go 语言带去一些小的改进,所以为 Go 1.14 选择了以下这些提案:

  • #32437 添加内置的 Go
    错误检查函数,”try” (design
    doc)
  • #6977 允许嵌入重叠的接口(overlapping
    interfaces) (design
    doc)
  • #32479 在go vet中对string(int)转换进行诊断
  • #32466 采用加密准则 (design
    doc)

下面举一个 try 语句的示例。

近况

本文发布时,官方表示目前在 Go 2 的提案中,大约有 120
个尚未解决且被标记为提案的
issue。这些提案都涉及到重要的库或语言特性变更,而它们通常不能与
Go 1 互相兼容。Ian Lance Taylor 和 Robert Griesemer
一直在研究这些提案,并对它们进行了分类(Go2Cleanup, NeedsDecision
等),以理解这些提案背后的含义并使它们后续更易进行。此外,他们还合并了相似的提案,并关闭了那些看似明显超出
Go 范围的提案,或者其他方面无法实现的提案。

早期出现的两个提案包括更好的错误处理和泛型,而它们的草案已在今年的
GopherCon
大会上发布,等待更多的探索发展。至于剩余的提案,官方提到,他们不希望过度影响数百万
Go 开发者以及现在的 Go 代码,更不想冒着分裂生态系统的风险去改版 Go
2,因此 Go 2
无法做出太多变更,每一个变更都需要仔细选择。为此,这些提案都将使用新的提案评估流程来决定去留与发展。

下一步

团队正在积极征求对这些提案的反馈意见。他们希望看到用户在基于事实的情况下,解释为什么提案可能在实践中不能很好地运作,或者指出团队在设计中欠缺考虑的问题等。对于仅包含个人意见的评论,团队表示可以承认它们,但无法以任何建设性的方式来解决这些问题。

最后,如果没有充分的理由阻止这些提案进入试验阶段,团队将会在 Go 1.14
的开发周期(2019年8月初开始)中实现它们,以便在实践中对其进行评估。根据提案评估流程,Go
1.14 预计将在开发周期结束时(2019年11月初)完成。

(文/开源中国)    

例如如下代码:

提案评估流程

提案评估流程旨在收集对少数选定提案的反馈意见,以作出最终决定。这个过程或多或少会与发布周期并行进行,包括以下步骤:

  1. 提案选择:Go 开发团队选择少量看起来值得考虑接受的 Go 2
    提案,但尚未做出最终决定。

  2. 提案反馈:Go
    开发团队将发布一份列出所选提案的公告,公告会向社区解释提案的初衷并收集反馈意见。在这个步骤中,社区可提出建议。

  3. 实现:根据来自社区的反馈意见,提案开始实现。

  4. 针对所实现的提案的反馈:在开发周期中,Go
    开发团队和社区试用新功能并且收集进一步的反馈意见。

  5. 启动决策:在三个月的开发周期结束时,根据在发布周期中收集的经验和反馈意见,Go
    开发团队会考虑变更的预期收益或产生的额外成本,从而最终决定是否发布每个变更。一旦发布,这些被发布的提案就成为语言和库的一部分。未被发布的提案可能会重新起草,但也有可能会被永久拒绝。

可以看到,通过两轮的反馈过程,可对提案进行有效的筛选,从而防止“功能蔓延(feature
creep)”,有助于保持 Go 语言的简洁。

 f, err := os.Open(filename)
if err != nil {
    return …, err  // zero values for other results, if any
}

提案选择标准

一项提案至少要满足以下这些条件:

  1. 解决大部分使用者觉得重要的问题

  2. 不会对其他使用者造成太大的影响

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

条件1确保提案所做的任何变更都可以帮助到尽可能多的 Go
开发者(使他们编写的代码更健壮、正确性更高等),条件2则保证了变更将给使用者带来的影响降到最低。

至于条件3,如果提案不能满足该条件,它将不会被实现。即便这项提案能够解决一个很重要的问题,思路也很好,但在没有实现方案的情况下,它将会被拒绝,并需要重新起草。

可通过使用 try 语句简化为:

下一步

在这篇文章发布时,Go
开发团队表示已经执行提案评估流程的第一步,并开始了流程的第二步,关于具体的提案可点此进行查看。

对于 Go
开发团队已经明确并通过的提案,将会继续实现(即评估流程的第3步)。开发团队表示希望在下一个发布周期的第一天(暂定于2019年2月1日)完成这些提案变更的实现,所以这次可能会在较早的时间开始进行,以留出两个月的反馈时间(2018年12月至2019年1月)。

而在为期3个月的开发周期中(2019年2月至5月),被选择的提案将会被实现,每位使用者都可以体验新功能并进行反馈(评估流程的第4步)。

最后,在短暂的冻结期后(2019年5月1日),Go
开发团队会最终决定是否永久保留新功能(并保证这些功能与 Go 1
兼容),或是放弃这些功能(评估流程的最后一步)。

Go
开发团队表示这是首次采用这一流程,因此在冻结阶段将会是反思这个流程,并在必要时进行调整的好机会。我们也不妨拭目以待吧!

(文/开源中国)    

 f := try(os.Open(filename))

可以看到,内置函数 try
采用一个单一表达式作为参数。表达式必须求出 n+1 个值(其中 n
可能为零),其中最后一个值必须是error类型。如果错误参数(final)为
nil,则返回前 n 个值(如果有),否则返回带有该错误的封闭函数。

图片 3

这种方法最主要的缺点是需要对错误结果参数进行命名,为此可能会导致 API
不够美观。总而言之,一开始try看起来就有点不寻常,因为它只是针对一个特定任务量身定制的语法糖,使用较少的样板代码进行错误处理,并且能足够好地处理该任务。不过它非常符合
Go 的哲学
——try不是为解决所有错误处理情况而设计的;它旨在很好地处理最常见的情况,以保持设计简单明了。

(文/开源中国)