Rust 团队很高兴地宣布 Rust 的新版本 1.56.0。此版本也稳定了 2021 Edition。Rust 是一种编程语言,旨在帮助每个人构建可靠且高效的软件。
如果您之前通过 rustup 安装了 Rust 的版本,那么获取 Rust 1.56.0 非常容易,只需
$ rustup update stable
如果您还没有安装,您可以从我们网站的相应页面获取 rustup
,并查看 GitHub 上1.56.0 的详细发行说明。
1.56.0 稳定版有哪些新内容
Rust 2021
我们在 五月份 撰写了关于 Rust 2021 Edition 的计划。Edition 是一种选择性更改的机制,这些更改可能存在向后兼容性风险。有关如何实现这一点的详细信息,请参阅edition 指南。与 2018 Edition 相比,这是一个较小的 Edition,但仍然有一些不错的提升生活质量的更改,这些更改需要选择加入 edition 才能避免破坏现有代码中的一些极端情况。有关每个新功能的更多详细信息和迁移指南,请参阅下面 edition 指南的新章节。
- 不相交捕获:闭包现在捕获单个命名字段,而不是总是捕获整个标识符。
- 数组的
IntoIterator
:array.into_iter()
现在通过值而不是通过引用迭代项目。 - macro-rules 中的 Or 模式 现在匹配
:pat
中的顶层A|B
。 - 默认 Cargo feature resolver 现在是版本 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 开始,闭包将自动仅捕获它们使用的字段,因此上面的示例将可以正常编译!
这种新行为仅在新 edition 中激活,因为它可能会更改字段被 drop 的顺序。与所有 edition 更改一样,自动迁移可用,它将通过在闭包内部插入 let _ = &a;
来更新对此有影响的闭包,以强制像以前一样捕获整个结构体。
迁移到 2021
该指南包括所有新功能的迁移说明,以及通常的将现有项目过渡到新的 edition。在许多情况下,cargo fix
可以自动执行必要的更改。您甚至可能会发现您的代码根本不需要为 2021 进行任何更改!
尽管这个 edition 在表面上看起来很小,但它仍然是许多贡献者辛勤工作的成果:请参阅我们专门的 庆祝和感谢 跟踪器!
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 之前的日子里是被允许的,但由于当时已知的不健全性而被删除。随着那时以来 borrow checker 的发展,以及经过大量的测试,编译器团队确定这在稳定的 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 edition。没有你们大家,我们不可能做到这一点。谢谢!