本周是 Rust 1.0 发布三个月。当我们开始进入 1.0 后的发展阶段时,我们想谈谈 **从后见之明来看,1.0 的意义,以及我们认为 Rust 在未来一年的发展方向**。
关于 1.0 的意义
Rust 1.0 的重点是稳定性、社区和清晰性。
-
关于**稳定性**,我们在之前的帖子中介绍我们的发布渠道和稳定流程时已经讨论了很多。
-
**社区**一直是 Rust 的最大优势之一。但在 1.0 发布前的一年中,我们引入并改进了 RFC 流程,最终通过子团队来管理每个特定领域的 RFC。社区对 RFC 的广泛讨论对于交付高质量的 1.0 版本至关重要。
-
在 1.0 之前进行的所有这些改进都是为了明确 Rust 的代表意义:
总而言之,**Rust 之所以令人兴奋,是因为它赋予了力量:你可以无所畏惧地进行编码**。并且你可以在以前可能没有过的环境中这样做,从 Ruby 或 Python 等语言下降,首次尝试系统编程。
这就是 Rust 1.0;但接下来会发生什么?
我们从这里走向何方
在核心团队、早期生产用户和更广泛的社区进行了大量讨论之后,我们确定了未来一年左右要进行的一些改进,这些改进分为三个类别:
- 加倍投入基础设施;
- 缩小关键功能中的差距;
- 扩展到使用 Rust 的新领域。
让我们来看看每个类别中一些最大的计划。
加倍投入:基础设施投资
Crater
Rust 的基本稳定性承诺是版本之间的升级是“无忧无虑”的。为了实现这一承诺,我们需要检测导致代码停止工作的编译器错误。当然,编译器有自己的大型测试套件,但这只是“在野外”存在的代码的一小部分。**Crater 是一种工具,旨在通过针对 crates.io 中找到的所有软件包测试编译器来弥合这一差距,从而让我们更好地了解是否有任何代码在最新的 nightly 版本中停止编译。**
Crater 很快成为不可或缺的工具。我们会定期将 nightly 版本与最新的稳定版本进行比较,并使用 crater 来检查正在进行的的分支并评估更改的影响。
有趣的是,我们经常发现,当代码停止编译时,并不是因为编译器中存在错误。相反,是因为我们*修复*了一个错误,而该代码恰好依赖于较旧的行为。即使在这些情况下,使用 crater 也可以通过建议我们应该通过警告逐步修复来帮助我们改善体验。
在未来一年左右的时间里,我们计划在多个方面改进 crater:
- 将覆盖范围扩展到 Linux 以外的其他平台,并在覆盖的库上运行测试套件。
- 使其更易于使用:留下
@crater: test
注释以试用 PR。 - 生成一个工具版本,库作者可以使用该工具来查看其更改对下游代码的影响。
- 包括来自 crates.io 以外的其他来源的代码。
增量编译
Rust 一直采用“crate 范围”的编译模型。这意味着 Rust 编译器会一次读取 crate 中的所有源文件。这些文件会进行类型检查,然后传递给 LLVM 进行优化。这种方法非常适合进行深度优化,因为它使 LLVM 可以完全访问整个代码集,从而可以进行更好的内联、更精确的分析等等。但是,这可能意味着周转速度很慢:即使你只编辑一个函数,我们也会重新编译所有内容。当项目变得很大时,这可能会成为负担。
增量编译项目的目标是通过让 Rust 编译器保存中间产物并重新使用它们来改变这种情况。这样,当你调试问题或调整代码路径时,**你只需重新编译你已更改的内容,这应该会使“编辑-编译-测试”周期快得多**。
该项目的一部分是重组编译器以引入新的中间表示,我们称之为 MIR。MIR 是一种更简单、更低级别的 Rust 代码形式,它简化了更复杂的功能,使编译器的其余部分更简单。这是非词法生命周期(在下一节中讨论)等语言更改的关键推动因素。
IDE 集成
一流的 IDE 支持可以帮助提高 Rust 的生产力。到目前为止,Racer、Visual Rust 和 Rust DT 等开创性项目主要是在没有编译器支持的情况下工作的。**我们计划扩展编译器,以允许与 IDE 和其他工具进行更深入的集成**;该计划最初将重点放在两个 IDE 上,然后再从那里发展。
聚焦:缩小关键功能中的差距
特化
零成本抽象的思想分解为两个独立的目标,正如 Stroustrup 所确定的那样:
- 你不使用的东西,你就不必为此付出代价。
- 你使用的东西,你不可能用手编码得更好。
Rust 1.0 在语言功能和标准库方面基本上实现了第一个目标。但它并没有完全实现第二个目标。以以下 trait 为例:
pub trait Extend<A> {
fn extend<T>(&mut self, iterable: T) where T: IntoIterator<Item=A>;
}
Extend
trait 提供了一种很好的抽象,用于将来自任何类型的迭代器的数据插入到集合中。但是,在今天的 trait 中,这也意味着每个集合只能提供一个适用于*所有*迭代器类型的实现,这需要实际重复调用 .next()
。在某些情况下,你可以用手编码得更好,例如,只需调用 memcpy
。
为了弥合这一差距,我们提出了 **特化,允许你提供多个重叠的 trait 实现,只要其中一个明显比另一个更具体即可**。除了为 Rust 提供更完整的零成本抽象工具包外,特化还改善了其代码重用的故事。有关更多详细信息,请参阅 RFC。
借用检查器改进
借用检查器在某种程度上是 Rust 的跳动心脏;它是编译器的一部分,通过捕获 use-after-free 错误等,使我们能够在没有垃圾回收的情况下实现内存安全。但有时,借用检查器也会“捕获”非错误,如下面的模式所示:
match map.find(&key) {
Some(...) => { ... }
None => {
map.insert(key, new_value);
}
}
像上面的代码片段这样的代码是完全没问题的,但借用检查器今天很难处理它,因为 map
变量在整个 match
主体中都被借用了,从而阻止它被 insert
修改。我们计划通过重构借用检查器来解决这个缺点,使其以更精细的(“非词法”)区域来查看代码——这是通过转移到上面提到的 MIR 来实现的。
插件
如果你愿意使用 Nightly 频道,今天你可以在 Rust 中做一些非常巧妙的事情。例如,regex crate 带有宏,可以在编译时将正则表达式直接转换为匹配它们的机器代码。或者以 rust-postgres-macros crate 为例,它会在编译时检查字符串的 SQL 语法有效性。像这样的 crate 利用了一个高度不稳定的编译器插件系统,该系统目前暴露了太多的编译器内部结构。**我们计划提出一种新的插件设计,该设计更健壮,并提供对卫生宏扩展的内置支持**。
扩展:将 Rust 带到新的领域
交叉编译
虽然今天可以使用 Rust 进行交叉编译,但它涉及大量的手动配置。**我们正在努力实现一键式交叉编译**。我们的想法是,为另一个目标编译 Rust 代码应该很容易:
- 如果你还没有为目标下载预编译版本的
libstd
。 - 执行
cargo build --target=foo
。 - 没有第 3 步。
Cargo 安装
Cargo 和 crates.io 是一个非常好的库分发工具,但它缺少任何安装可执行文件的方法。RFC 1200 描述了对 cargo 的一个简单添加,即 cargo install
命令。与传统的 make install
非常相似,**cargo install
会将可执行文件放置在你的路径中,以便你可以运行它**。这可以作为一个简单的分发渠道,对于编写以 Rust 开发人员为目标的工具的人特别有用(他们可能熟悉运行 cargo)。
跟踪钩子
使用 Rust 最有前景的方式之一是将 Rust 代码“嵌入”到使用更高级语言编写的系统中,例如 Ruby 或 Python。这种嵌入通常通过为 Rust 代码提供 C API 来实现,当目标采用“C 友好”的内存管理方案(如引用计数或保守 GC)时,效果相当不错。
与使用更高级 GC 的环境集成可能会非常具有挑战性。最突出的例子或许是 JavaScript 引擎,例如 V8(由 node.js 使用)和 SpiderMonkey(由 Firefox 和 Servo 使用)。与这些引擎集成需要非常谨慎的编码,以确保所有对象都正确地被根引用;小的错误很容易导致崩溃。而这些正是 Rust 旨在消除的内存管理问题。
为了将 Rust 带入具有高级 GC 的环境,我们计划扩展编译器,使其能够生成“跟踪钩子”。GC 可以使用这些钩子来扫描堆栈并识别根,从而可以编写能够与高级 VM 平滑且轻松集成的代码。当然,该设计将尊重 Rust 的“按需付费”原则,因此不与 GC 集成的代码不会受到影响。
尾声:RustCamp 2015 和 2016 年的 Rust 社区
我们最近举办了有史以来第一次 Rust 会议,RustCamp 2015,有 160 名与会者,门票全部售罄。看到如此多的 Rust 社区成员亲临现场,并看到我们在线空间的氛围转化为友好且平易近人的线下活动,真是令人惊叹。第一天以 Nicholas Matsakis 和 Aaron Turon 的主题演讲开幕,他们阐述了核心团队对我们所处位置以及未来发展方向的看法。幻灯片已在网上提供(以及其他几个演讲),以上内容可以作为缺失的背景音乐。 更新:现在您还可以观看演讲视频!
当天有一个明确的主题:Rust 最大的潜力是开启新一代系统程序员。这不仅仅是因为语言本身;还因为社区文化提倡“不知道堆栈和堆的区别?不用担心,Rust 是了解它的好方法,我很乐意向你展示如何学习。”
我们上面概述的技术工作对于我们在 2016 年的愿景至关重要,我们社区管理和社区团队的工作,以及所有那些不知疲倦地(热情地)欢迎来自各种背景的人们加入 Rust 社区的人们的工作,也同样重要。因此,我们对 Rust 未来一年的最大愿望是,随着社区的发展,它能够继续保持今天所拥有的欢迎精神。