Rust 团队很高兴地宣布最新版本的 Rust,1.21.0。Rust 是一种专注于安全性、速度和并发性的系统编程语言。
如果您已经安装了 Rust 的早期版本,那么获取 Rust 1.21 非常简单,只需执行以下命令:
$ rustup update stable
如果您还没有安装 Rust,您可以从我们网站上的相应页面获取rustup
,并查看 GitHub 上1.21.0 的详细发行说明。
1.21.0 稳定版的新特性
此版本包含一些非常小的但很实用的功能,以及一些新的文档。
首先,是对字面量的一个小改动。考虑像这样的代码:
let x = &5;
在 Rust 中,这段代码等同于:
let _x = 5;
let x = &_x;
也就是说,这里的5
将存储在堆栈中,或者可能在寄存器中。x
将是对它的引用。
然而,鉴于它是一个字面整数,没有理由它必须像这样是本地的。想象一下,我们有一个函数接受一个 'static
参数,例如 std::thread::spawn
。你可能会像这样使用 x
:
use std::thread;
fn main() {
let x = &5;
thread::spawn(move || {
println!("{}", x);
});
}
在之前的 Rust 版本中,这将无法编译:
error[E0597]: borrowed value does not live long enough
--> src/main.rs:4:14
|
4 | let x = &5;
| ^ does not live long enough
...
10 | }
| - temporary value only lives until here
|
= note: borrowed value must be valid for the static lifetime...
因为 5
是本地的,所以它的借用也是本地的,这不满足 spawn
的要求。
但是,如果您在 Rust 1.21 上编译这段代码,它将可以工作。为什么呢?好吧,如果被引用的内容可以放入 static
中,我们可以将 let x = &5;
解糖为这样:
static FIVE: i32 = 5;
let x = &FIVE;
在这里,由于 FIVE
是 static
,x
是一个 &'static i32
。因此,这就是 Rust 现在在这种情况下会做的事情。有关详细信息,请参阅 RFC 1414,该 RFC 在 1 月份被接受,但始于 2015 年 12 月!
我们现在在生成代码时并行运行 LLVM,这应该可以减少峰值内存使用量。
RLS 现在可以通过调用 rustup component add rls-preview
通过 rustup 安装。一般来说,许多有用的 Rust 开发工具(如 RLS、Clippy 和 rustfmt
)都需要 nightly Rust;这是使它们在 stable Rust 上工作的首要步骤。请查看预览版,您将在未来听到更多关于这些计划的消息。
最后,是一些文档改进。首先,如果您访问std::os
的文档,其中包含特定于操作系统的功能,您现在将看到不仅仅是 linux
,即我们构建文档的平台。长期以来,我们一直对托管版本的文档是特定于 Linux 的而感到遗憾;这是朝着纠正这一点的第一步。这仅适用于标准库,不适用于一般用途;我们希望将来能进一步改进这一点。
接下来,Cargo 的文档正在迁移! 从历史上看,Cargo 的文档托管在 doc.crates.io 上,即使 Cargo 本身遵循发布周期模型,它也不遵循该模型。这导致了一些情况,即一个功能会在 Cargo nightly 中落地,文档会被更新,然后在长达 12 周的时间里,用户会认为它应该可以工作,但实际上还不能。https://doc.rust-lang.net.cn/cargo 将是 Cargo 文档的新家,但目前,该 URL 是重定向到 doc.crates.io。未来的版本将把 Cargo 的文档迁移过来,到那时,doc.crates.io 将重定向到 doc.rust-lang.org/cargo。Cargo 的文档长期以来需要更新,因此预计未来会听到更多关于 Cargo 文档的总体新闻!
最后,直到现在,rustdoc
没有任何文档。现在,这已修复,新的“rustdoc
书”位于 https://doc.rust-lang.net.cn/rustdoc。这些文档目前相当简陋,但我们会随着时间的推移对其进行改进。
有关更多信息,请参阅详细发行说明。
库的稳定化
此版本中没有太多稳定化,但是有一个非常棒的质量改进:由于缺少类型级整数,数组仅支持大小最大为 32 的各种 trait。 现在已为 Clone
trait 修复了此问题,这有时也会导致许多 ICE,当类型是 Copy
而不是 Clone
时。对于其他 trait,最近接受了一个关于类型级整数的 RFC,这可能会对此情况有所帮助。但是,该更改尚未实现,尽管目前正在进行先决条件工作。
接下来,Iterator::for_each
已经稳定,允许您消费一个迭代器以产生副作用,而无需 for
循环:
// old
for i in 0..10 {
println!("{}", i);
}
// new
(0..10).for_each(|i| println!("{}", i));
要使用哪一个取决于你的情况;在上面的示例中,for
循环非常简单。但是当您将多个迭代器链接在一起时,for_each
版本有时会更清晰。考虑这个:
// old
for i in (0..100).map(|x| x + 1).filter(|x| x % 2 == 0) {
println!("{}", i);
}
// new
(0..100)
.map(|x| x + 1)
.filter(|x| x % 2 == 0)
.for_each(|i| println!("{}", i));
Ord
trait 上的 max
和 min
函数现在是稳定的。
needs_drop
内置函数现在是稳定的。
最后,std::mem::discriminant
已经稳定,允许您查看 enum
实例的哪个变体,而无需 match
语句。
有关更多信息,请参阅详细发行说明。
Cargo 功能
除了上面列出的文档功能外,Cargo 在此版本中获得了一项主要功能:[patch]
。在 RFC 1969 中设计,当您想要覆盖依赖关系图的某些部分时,可以使用 Cargo.toml
的 [patch]
部分。我们还有一个功能,[replace]
,它具有类似的功能。在许多方面,[patch]
是新的 [replace]
,虽然我们没有计划弃用或删除 [replace]
,但在这一点上,您应该使用 [patch]
而不是 [replace]
。
它看起来像什么?假设我们有一个 Cargo.toml
看起来像这样:
[dependencies]
foo = "1.2.3"
此外,我们的 foo
crate 依赖于 bar
crate,我们在 bar
中发现了一个 bug。为了测试这一点,我们将下载 bar
的源代码,然后更新我们的 Cargo.toml
:
[dependencies]
foo = "1.2.3"
[patch.crates-io]
bar = { path = '/path/to/bar' }
现在,当您执行 cargo build
时,它将使用本地版本的 bar
,而不是 foo
依赖的来自 crates.io
的版本。
有关更多详细信息,请参阅文档。
此外
- 您现在可以一次
cargo install
多个 crate - 如果您在虚拟工作区中,则
--all
现在会自动应用. - 您的
Cargo.toml
中的include
和exclude
字段接受类似于.gitignore
的模式.
有关更多信息,请参阅详细发行说明。
1.21.0 的贡献者
许多人共同努力创建了 Rust 1.21。没有大家,我们不可能做到这一点。谢谢!