Rust 团队很高兴宣布 Rust 的最新版本 1.21.0。Rust 是一种系统编程语言,专注于安全、速度和并发。
如果你已经安装了旧版本的 Rust,获取 Rust 1.21 非常简单
$ rustup update stable
如果你还没有安装,你可以从我们网站上的相应页面获取 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 安装,方法是调用 rustup component add rls-preview
。一般来说,许多有用的 Rust 开发工具,如 RLS、Clippy 和 rustfmt
需要 nightly Rust;这是让它们在稳定版 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 的各种特征。这个问题现在已经针对 Clone
特征得到解决,这也导致了在某些情况下出现很多 ICE,当类型是 Copy
但不是 Clone
时。对于其他特征,最近接受了关于类型级整数的 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
特征上的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
箱子依赖于 bar
箱子,我们发现 bar
中存在一个错误。为了测试这一点,我们将下载 bar
的源代码,然后更新我们的 Cargo.toml
[dependencies]
foo = "1.2.3"
[patch.crates-io]
bar = { path = '/path/to/bar' }
现在,当你 cargo build
时,它将使用 bar
的本地版本,而不是 foo
依赖于 crates.io
上的版本。
有关更多详细信息,请参阅文档。
此外
- 你现在可以一次
cargo install
多个箱子 - 如果你在虚拟工作区中,
--all
现在会自动应用. Cargo.toml
中的include
和exclude
字段接受类似于.gitignore
的模式.
查看详细的发布说明以了解更多信息。
1.21.0 的贡献者
许多人共同创建了 Rust 1.21。没有你们,我们无法做到。 感谢!