Rust 2021 版计划

我们很高兴宣布 Rust 语言的第 3 版 Rust 2021 计划于 10 月发布。Rust 2021 包含许多细微的变化,但是这些变化有望大大改善 Rust 在实践中的感受。

什么是版本?

Rust 1.0 的发布确立了 “不停滞的稳定性”(stability without stagnation) 作为 Rust 的核心指导原则。自 1.0 版发布以来,Rust 的原则是,一旦某个功能在稳定版上发布,我们将致力于在所有将来的发行版中都支持该功能。

但是,有时可以对不向后兼容的语言进行小的更改很有用。最明显的示例是引入一个新关键字,该关键字会使具有相同名称的变量无效。例如,Rust 的第一个版本号没有 asyncawait 关键字。突然在更高版本号中将这些单词更改为关键字会破坏像 let async = 1; 这样的代码。

(译注:此处是 edition,区别于 version,因为汉语中这两个单词意识均为“版本”,原文中多次使用了 edition 和 version,故下文均用“版本”或“版”表示 edition,“版本号”表示 version)是我们用来解决此问题的机制。当我们想要发布一个向后不兼容的功能时,我们将其作为新 Rust 版的一部分发布。版本是选择加入的,因此,现有的 crate 除非将其明确迁移到新的版本,否则不会看到这些更改。这意味着,即使 Rust 的最新版本号仍然没有把 async 作为关键字,除非选择 2018 版或更高版。此选择是由每个 crate 包含的 Cargo.toml 来确定。通过 cargo new 创建新 crate 通常会配置为使用最新的稳定版。

版本不会分裂生态系统

版本的最重要原则是,一个版本中的 crate 可以与其他版本中编译的 crate 无缝地互操作。这样可以确保决定迁移到较新的版本是私有的,而这个 crate 不会影响其他版本的 crate。

crate 互操作性的要求对我们在一个版本中可以进行的更改种类有一定的限制。通常,一个版本中发生的更改往往是“细微的”(skin deep)。不管版本如何,所有 Rust 代码最终都会在编译器中编译为相同的内部表示形式。

版本迁移很容易,而且自动化程度很高

我们的目标是使 crate 轻松升级到新版本。发布新版本时,我们还提供了自动迁移的工具。为了使它与新版本兼容,它需要对代码进行较小的更改。例如,当迁移到 Rust 2018 时,将使用等效的原始标识符语法 r#async 替换任何为 async 的名称。

自动迁移不一定是完美的:在某些极端情况下,仍然需要手动更改。该工具尽力避免对语义的更改,这些更改可能影响代码的正确性或性能。

除工具外,我们还维护《版本迁移指南》,其中涵盖了版本中的更改。本指南将描述更改,并提供指向人们可以在其中了解更多信息的指南。它还将涵盖人们应注意的任何极端情况或细节。该指南既可以作为该版本的概述,也可以作为人们在使用自动化工具时遇到问题的快速故障排除参考。

Rust 2021 计划做出哪些更改?

在过去的几个月中,Rust 2021 工作组已经就新版本中包含的内容提出了许多建议。我们很高兴地宣布版本变更的最终清单。每个功能都必须满足两个条件才能列出该列表。首先,它们必须得到适当的 Rust 团队的批准。第二,它们的实施必须足够远,以使我们确信,它们将按计划的里程碑及时完成。

prelude 的补充

标准库的 prelude 是模块(译注:prelude 一般指音乐、表演的开场、序曲等,Rust 语言是借用了这个概念),其中包含在每个模块中自动导入的所有内容。它包含常用的项,例如 OptionVecdropClone

Rust 编译器会优先处理任何手动导入的项目,使其优先于 prelude 中的项,以确保在 prelude 中添加的内容不会破坏任何现有代码。例如,如果你有一个名为 example 的 crate 或模块包含了一个 pub struct Option;,那么 use example::*; 将把 Option 明确地引用 example 的一个项,而不是标准库中的项。

但是,在 prelude 中添加 trait 可能会以不易察觉的方式破坏现有代码。如果 stdTryInto 也被导入,那么使用 MyTryInto trait 调用 x.try_into() 可能变得模糊和无法编译,因为两者提供了具有相同名称的方法。这就是我们尚未添加 TryInto prelude 的原因,因为有很多代码会破坏这种方式。

作为解决方案,Rust 2021 将使用新的 prelude。除了三个新增功能外,它与当前的相同:

默认的 Cargo 功能解析器

自 Rust 1.51.0 起,Cargo 启用了对新功能解析器的支持,可以在 Cargo.toml 中使用 resolver = "2" 激活它。

从 Rust 2021 开始,这将是默认设置。也就是说,配置 edition = "2021"Cargo.toml 会暗示 resolver = "2"

新的功能解析器不再合并所有请求的功能,这些功能将以多种方式依赖于 Cargo。有关详细信息,请参见 Rust 1.51 的发布公告

(还有几个小节待翻译补充完)...

接下来是什么?

我们的计划是在 9 月之前合并并完全测试这些更改,以确保 2021 年版本将其纳入 Rust 1.56.0。Rust 1.56.0 将在 Beta 中进行六周测试,此后于 10 月 21 日稳定发布。

但是请注意,Rust 是一个由志愿者运行的项目。我们优先考虑在 Rust 上工作的每个人的个人福祉,而不是我们设定的任何截止日期和期望。这可能意味着如果需要,可以推迟版本的发布,或者放弃一项功能,事实证明该功能太困难或压力太大,无法及时完成。

就是说,由于所有为 Rust 2021 做出贡献的人们,我们正在按计划进行,许多难题已经得到解决!💛


您可能会在 7 月份收到有关该新版本的另一个公告。届时,我们希望所有更改和自动迁移都将实施,并准备进行公开测试。

我们将很快在 “Inside Rust” 博客上发布有关该过程的更多详细信息和拒绝提案。