附录 G - Rust 的构建方式和“Nightly Rust”

本附录将介绍 Rust 是如何构建的,以及这对作为 Rust 开发者的你有什么影响。

稳定而不停滞

作为一门语言,Rust 非常重视代码的稳定性。我们希望 Rust 成为你可以依赖的坚实基础,如果事物不断变化,那将是不可能的。同时,如果我们不能尝试新特性,可能直到发布后才能发现重要的缺陷,而那时我们已经无法再做改变了。

我们对这个问题的解决方案称之为“稳定而不停滞”,我们的指导原则是:你不必担心升级到新的稳定版 Rust。每次升级都应该平稳进行,同时带来新特性、更少的 Bug 和更快的编译速度。

呜,呜!发布通道和“搭乘火车”

Rust 的开发遵循一种火车时刻表模式。也就是说,所有的开发都在 Rust 仓库的 master 分支上进行。发布遵循软件发布列车模型,这种模型已被 Cisco IOS 和其他软件项目使用。Rust 有三种发布通道

  • Nightly
  • Beta
  • Stable

大多数 Rust 开发者主要使用 stable 通道,但那些想尝试实验性新特性的开发者可能会使用 nightly 或 beta。

这里有一个开发和发布过程如何运作的例子:假设 Rust 团队正在开发 Rust 1.5 版本。这个版本在 2015 年 12 月发布,它将为我们提供真实的版本号。一个新特性被添加到 Rust 中:一个新的提交落到 master 分支上。每晚都会产生一个 Rust 的新的 nightly 版本。每天都是发布日,这些版本由我们的发布基础设施自动创建。所以随着时间的推移,我们的发布版本每晚都会像这样

nightly: * - - * - - *

每六周,就该准备一个新的发布版本了!Rust 仓库的 beta 分支会从 nightly 使用的 master 分支分出。现在,有两个发布版本

nightly: * - - * - - *
                     |
beta:                *

大多数 Rust 用户不主动使用 beta 版本,但在其 CI 系统中针对 beta 进行测试,以帮助 Rust 发现可能的回归。与此同时,每晚仍然有一个 nightly 版本发布

nightly: * - - * - - * - - * - - *
                     |
beta:                *

假设发现了一个回归。幸好我们在回归潜入稳定版本之前有时间测试 beta 版本!修复被应用到 master 分支,这样 nightly 版本就被修复了,然后修复被回迁(backported)到 beta 分支,并产生一个新的 beta 版本

nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *

在第一个 beta 版本创建六周后,就该发布 stable 版本了!stable 分支从 beta 分支产生

nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *

太好了!Rust 1.5 完成了!然而,我们忘了一件事:因为六周已经过去了,我们还需要 Rust 下一个版本 1.6 的新 beta 版本。所以,在 stablebeta 分出后,下一个版本的 beta 会再次从 nightly 分出

nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *

这被称为“火车模型”,因为每六周,一个发布版本就会“离站”,但它仍然需要经过 beta 通道才能最终成为 stable 版本抵达。

Rust 每六周发布一次,像时钟一样准时。如果你知道某个 Rust 版本的发布日期,你就能知道下一个版本的日期:就在六周后。每六周安排发布的一个好处是下一班火车很快就来了。如果某个特性恰好错过了某个发布版本,也不用担心:很快就会有下一个发布版本!这有助于减轻在接近发布截止日期时偷偷塞入可能不完善的特性的压力。

多亏了这个流程,你总能检出下一个 Rust 构建版本,并亲自验证升级是否容易:如果 beta 版本不像预期那样工作,你可以向团队报告,并在下一个 stable 版本发布前得到修复!beta 版本出现问题的情况相对较少,但 rustc 仍然是一个软件,Bug 确实存在。

维护时间

Rust 项目支持最新的稳定版本。当一个新的稳定版本发布时,旧版本就达到了生命周期结束(EOL)。这意味着每个版本都会被支持六周。

不稳定特性

这个发布模型还有一个需要注意的地方:不稳定特性。Rust 使用一种称为“特性标志(feature flags)”的技术来确定在给定版本中启用哪些特性。如果一个新特性正在积极开发中,它会进入 master 分支,因此也会出现在 nightly 版本中,但会隐藏在特性标志后面。如果你作为用户想尝试这个正在开发中的特性,可以,但你必须使用 nightly 版本的 Rust,并在源代码中用适当的标志进行注解来选择启用。

如果你使用的是 beta 或 stable 版本的 Rust,你不能使用任何特性标志。这是我们在永远宣布新特性稳定之前获得实际使用的关键。那些希望体验最前沿特性的人可以这样做,而那些想要坚如磐石的体验的人可以坚持使用 stable 版本,并且知道他们的代码不会被破坏。稳定而不停滞。

本书只包含 stable 特性的信息,因为正在开发中的特性仍在变化,而且它们在本书编写时和在 stable 构建版本中启用时肯定会有所不同。你可以在线查找 nightly-only 特性的文档。

Rustup 和 Rust Nightly 的作用

Rustup 使全局或按项目切换不同的 Rust 发布通道变得容易。默认情况下,你会安装 stable Rust。例如,要安装 nightly 版本

$ rustup toolchain install nightly

你也可以用 rustup 查看你安装的所有工具链(Rust 及其相关组件的发布版本)。这是一个在作者之一的 Windows 电脑上的例子

> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

如你所见,stable 工具链是默认的。大多数 Rust 用户大部分时间都使用 stable 版本。你可能想大部分时间使用 stable 版本,但在特定项目上使用 nightly 版本,因为你关心某个前沿特性。要做到这一点,你可以在该项目的目录中使用 rustup override 来设置 nightly 工具链,使其成为你在该目录中时 rustup 应该使用的工具链

$ cd ~/projects/needs-nightly
$ rustup override set nightly

现在,每当你在 ~/projects/needs-nightly 目录内调用 rustccargo 时,rustup 都会确保你使用的是 nightly Rust,而不是默认的 stable Rust。当你有很多 Rust 项目时,这会非常方便!

RFC 流程和团队

那么如何了解这些新特性呢?Rust 的开发模式遵循一种 Request For Comments (RFC) 流程。如果你想改进 Rust,可以撰写一份提案,称为 RFC。

任何人都可以撰写 RFC 来改进 Rust,这些提案由 Rust 团队审查和讨论,该团队由许多主题子团队组成。在 Rust 官网上 有完整的团队列表,其中包括项目各个领域的团队:语言设计、编译器实现、基础设施、文档等等。相应的团队会阅读提案和评论,写下他们自己的评论,最终达成接受或拒绝该特性的共识。

如果特性被接受,Rust 仓库上就会创建一个 Issue,然后有人可以实现它。实现它的人很可能不是最初提出这个特性的人!当实现准备好后,它会进入 master 分支,并隐藏在特性门(feature gate)后面,正如我们在“不稳定特性”一节中讨论的那样。章节。

过一段时间后,一旦使用 nightly 版本的 Rust 开发者能够尝试新特性,团队成员就会讨论该特性,它在 nightly 版本中的表现如何,并决定它是否应该进入 stable Rust。如果决定继续推进,特性门就会被移除,这个特性现在就被认为是稳定的了!它会搭乘火车进入新的 stable Rust 版本。