即将发布的 Rust 1.0 版本意义重大,但最根本的是,除了我们长期以来对安全的承诺之外,它更是对稳定性的承诺。
从 1.0 开始,我们将采用为期 6 周的发布周期和一系列发布“渠道”。稳定发布渠道将提供无痛升级,而 nightly 渠道将允许早期采用者在我们开发时访问未完成的功能。
承诺稳定性
自 Rust 的早期阶段以来,只有两件事是可以指望的:安全性和变化。有时甚至不是第一件。在开发 Rust 的过程中,我们遇到了许多死胡同,因此拥有根据需要更改语言的自由至关重要。
但 Rust 已经成熟,并且该语言的核心方面长期以来一直保持稳定。设计感觉是对的。而且,人们对 Rust 积攒了巨大的兴趣,正等待 1.0 发布,以便有一个稳定的基础来构建。
清楚我们所说的稳定是什么意思很重要。我们并不是说 Rust 将停止发展。我们将定期频繁地发布新的 Rust 版本,并且我们希望人们也会同样定期地进行升级。但要实现这一点,这些升级需要是无痛的。
简单来说,我们的责任是确保你绝不会害怕升级 Rust。如果你的代码能在 Rust 稳定版 1.0 上编译通过,那么它应该能在 Rust 稳定版 1.x 上以最小的麻烦编译通过。
计划
我们将采用火车模型的变体,该模型最初在网络浏览器中引入,现在被广泛用于在不停滞的情况下提供稳定性。
-
新的开发工作直接进入 master 分支。
-
每天,master 分支的最后一次成功构建将成为新的 nightly 版本。
-
每六周,会从 master 的当前状态创建一个 beta 分支,并将之前的 beta 版提升为新的稳定版。
简而言之,有三个发布渠道——nightly、beta 和 stable——它们之间会定期频繁地进行升级。
新功能和新 API 将分别通过 feature gates 和 stability attributes 标记为不稳定。不稳定功能和标准库 API 将仅在 nightly 分支上可用,并且只有在你明确“选择加入”不稳定时才可用。
另一方面,beta 和 stable 版本将只包含被视为稳定的功能和 API,这代表着避免破坏使用这些功能或 API 的代码的承诺。
常见问题解答 (FAQ)
上述过程涉及许多细节,我们计划发布 RFC 来阐述要点。本文的其余部分将介绍此计划的一些最重要细节和潜在担忧。
哪些功能将在 1.0 中稳定?
我们已经对当前的 Rust 生态系统进行了分析,以确定最常用的 crate 及其依赖的 feature gates,并使用这些数据来指导我们的稳定计划。好消息是,目前正在使用的绝大多数功能将在 1.0 版本之前稳定。
-
有几个功能已经接近完成:结构体变体(struct variants)、默认类型参数(default type parameters)、元组索引(tuple indexing)和切片语法(slicing syntax)。
-
有两个关键功能需要大量额外工作,但对 1.0 至关重要:未装箱闭包(unboxed closures)和关联类型(associated types)。
-
最后,有一些广泛使用的功能存在缺陷,无法在 1.0 的时间范围内解决:glob 导入、宏(macros)和语法扩展(syntax extensions)。这是我们需要做出一些艰难决定的地方。
经过广泛讨论,我们计划在 1.0 中将 globs 和 macros 作为稳定功能发布。对于 globs,我们相信可以通过向后兼容的方式解决问题。对于宏,我们将来可能会提供另一种定义宏的方式(具有更好的卫生性(hygiene)),并在此之前逐步改进“macro rules”功能。1.0 版本将稳定所有当前的宏支持,包括导入/导出。
另一方面,我们不能稳定语法扩展(syntax extensions),它们是完全访问编译器内部的插件。稳定它实际上会永久冻结编译器的内部;我们需要设计一个更周密的扩展与编译器之间的接口。因此,语法扩展在 1.0 中仍将保留在 feature gate 之后。
语法扩展的许多主要用途可以替换为传统的代码生成,并且 Cargo 工具很快将增加对此用例的特定支持。我们计划与库作者合作,帮助他们在 1.0 之前从语法扩展迁移。由于许多语法扩展不符合此模型,因此我们也将稳定语法扩展视为 1.0 发布后的当务之急。
标准库的哪些部分将在 1.0 中稳定?
我们一直在稳步稳定标准库,并制定了几乎所有模块的计划。预计标准库中的绝大多数功能将在 1.0 中稳定。我们也将更多实验性 API 从标准库迁移到其自身的 crate 中。
标准库之外的稳定性属性呢?
库作者可以像今天一样继续使用稳定性属性来标记他们自己的稳定性承诺。这些属性默认不与 Rust 发布渠道绑定。也就是说,当你在 Rust stable 上编译时,你只能使用标准库中的稳定 API,但你可以选择使用其他库中的实验性 API。Rust 发布渠道旨在使升级 Rust 本身(编译器和标准库)无痛。
库作者应遵循语义版本控制(semver);我们很快将发布一个 RFC,定义库稳定性属性与 semver 如何交互。
为什么不允许在稳定版中选择使用不稳定功能?
在稳定版本中允许使用不稳定功能存在三个问题。
首先,正如网络已经多次表明的那样,仅仅宣称不稳定是无效的。一旦功能被广泛使用,就很难更改它们——而且一旦功能可用,就很难阻止它们被使用。网络上像“厂商前缀(vendor prefixes)”这样原本旨在支持实验的机制,最终却导致了事实上的标准化。
其次,不稳定功能从定义上来说是正在进行中的工作。但是 beta/stable 快照会在预定时间点冻结该功能,而库作者会希望使用该功能的最新版本。
最后,我们根本无法为 Rust 提供稳定性,除非我们强制执行。我们的承诺是,如果你使用的是 Rust 的稳定版本,你永远不会害怕升级到下一个版本。如果库可以选择使用不稳定功能,那么我们只有在所有库作者通过同时支持所有三个发布渠道来保证同样的事情时,才能兑现这个承诺。
要求整个生态系统完美地处理这些问题既不现实也不必要。相反,我们将强制执行稳定意味着稳定:稳定渠道只提供稳定的功能。
这会分裂生态系统吗?在 1.0 发布时大家都会使用 nightly 吗?
这不会分裂生态系统:它会创建一个子集。使用 nightly 发布渠道的程序员可以自由使用为 stable 渠道设计的库。重要功能和 API 将面临稳定的压力,因此随着时间的推移,留在不稳定世界的动力将会减小。
我们仔细规划了 1.0 版本,以便现有生态系统的大部分都将属于“稳定”类别,因此 Rust 的新用户将能够立即在稳定版 1.0 上使用大多数库。
稳定性的注意事项有哪些?
我们保留修复编译器错误、修补安全漏洞以及以可能偶尔需要新的类型注解的方式更改类型推断的权利。我们不认为这些更改在升级 Rust 时会导致麻烦。
库 API 的注意事项将在即将发布的 RFC 中阐述,但同样旨在最大程度地减少实际升级时的痛苦。
Rust 及其生态系统会继续快速发展吗?
是的!由于新的开发工作可以随时合并到 master 分支,火车模型不会减缓开发速度或引入人为延迟。Rust 始终以快速的速度发展,得到了许多出色的社区成员的帮助,我们预计这将只会加速。