Rust 团队很高兴地宣布 Rust 的新版本 1.56.0 发布。此版本也同时稳定了 2021 版本。Rust 是一种编程语言,它使每个人都能够构建可靠且高效的软件。
如果您之前通过 rustup 安装了 Rust 版本,那么获取 Rust 1.56.0 就很简单,只需执行:
$ rustup update stable
如果您还没有安装,可以从我们网站上的相应页面获取 rustup
,并查看 GitHub 上1.56.0 的详细发行说明。
1.56.0 稳定版中的新特性
Rust 2021
我们曾在5月份撰写过关于 Rust 2021 版本计划的文章。版本是选择加入机制,用于引入可能存在向后兼容风险的更改。有关如何实现这一点的详细信息,请参阅版本指南。这是一个较小的版本,特别是与 2018 版本相比,但仍然有一些不错的质量改进,需要选择加入版本以避免破坏现有代码中的某些极端情况。请参阅下面版本指南的新章节,了解每个新功能的更多详细信息以及迁移指南。
- 闭包中的不相交捕获:闭包现在捕获单个命名字段,而不是总是捕获整个标识符。
- 数组的
IntoIterator
:array.into_iter()
现在按值而不是按引用迭代项目。 - macro-rules 中的 Or 模式现在匹配
:pat
中的顶层A|B
。 - 默认 Cargo 特性解析器现在是版本 2。
- 添加到 prelude:
TryInto
、TryFrom
和FromIterator
现在默认处于作用域中。 - Panic 宏现在总是像
println!()
一样期望格式化字符串。 - 为
ident#
、ident"..."
和ident'...'
保留语法。 - 警告提升为错误:
bare_trait_objects
和ellipsis_inclusive_range_patterns
。
闭包中的不相交捕获
闭包自动捕获主体中使用的标识符的值或引用,但在 2021 年之前,它们总是被作为一个整体捕获。新的不相交捕获功能可能会简化你编写闭包的方式,让我们看一个简单的例子
// 2015 or 2018 edition code
let a = SomeStruct::new();
// Move out of one field of the struct
drop(a.x);
// Ok: Still use another field of the struct
println!("{}", a.y);
// Error: Before 2021 edition, tries to capture all of `a`
let c = || println!("{}", a.y);
c();
要修复此问题,您必须在闭包之前手动提取类似 let y = &a.y;
的内容来限制其捕获。从 Rust 2021 开始,闭包将自动仅捕获它们使用的字段,因此上面的示例可以正常编译!
此新行为仅在新版本中激活,因为它会更改字段的丢弃顺序。对于所有版本更改,都有一个自动迁移可用,它将通过在闭包内部插入 let _ = &a;
来更新你的闭包,强制像以前一样捕获整个结构体。
迁移到 2021
该指南包括所有新功能的迁移说明,并且通常将现有项目迁移到新版本。在许多情况下,cargo fix
可以自动执行必要的更改。你甚至可能会发现 2021 不需要对你的代码进行任何更改!
尽管这个版本表面上看起来很小,但它仍然是许多贡献者辛勤工作的成果:请查看我们专门的庆祝和感谢跟踪器!
rust-version
Cargo Cargo.toml
现在支持 [package]
rust-version
字段,用于指定 crate 支持的最低 Rust 版本,如果未满足此要求,Cargo 将提前退出并显示错误。这目前不会影响依赖项解析器,但其目的是在兼容性问题转化为神秘的编译器错误之前捕获它们。
binding @ pattern
中的新绑定
Rust 模式匹配可以使用单个标识符来绑定整个值,后跟 @
和更精细的结构模式来编写,但这不允许在该模式中添加其他绑定——直到现在!
struct Matrix {
data: Vec<f64>,
row_len: usize,
}
// Before, we need separate statements to bind
// the whole struct and also read its parts.
let matrix = get_matrix();
let row_len = matrix.row_len;
// or with a destructuring pattern:
let Matrix { row_len, .. } = matrix;
// Rust 1.56 now lets you bind both at once!
let matrix @ Matrix { row_len, .. } = get_matrix();
这实际上在 Rust 1.0 之前的日子里是被允许的,但由于当时已知的不健全性而被删除。随着自那时以来借用检查器的发展,以及大量的测试,编译器团队确定这最终可以在稳定的 Rust 中允许使用!
稳定的 API
以下方法和 trait 实现已稳定。
std::os::unix::fs::chroot
UnsafeCell::raw_get
BufWriter::into_parts
core::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}
(以前仅在std
中)Vec::shrink_to
String::shrink_to
OsString::shrink_to
PathBuf::shrink_to
BinaryHeap::shrink_to
VecDeque::shrink_to
HashMap::shrink_to
HashSet::shrink_to
以下先前稳定的函数现在是 const
。
其他更改
Rust 1.56.0 版本中还有其他更改:查看Rust、Cargo 和 Clippy 中的更改。
1.56.0 的贡献者
许多人齐心协力创建了 Rust 1.56.0 和 2021 版本。没有你们所有人,我们不可能完成这项工作。谢谢!