Rust 1.56.0 版本已正式发布,此版本支持闭包对标识符的非联接捕获,并对 pattern做了大量优化。
且如果你此前已通过 rustup 安装了以前的 Rust 版本,运行以下命令即可升级至最新版本:
$ rustup update stable
1.56.0 版本主要更新内容:
- 非联接捕获:闭包现在捕获单个命名字段,不会总是捕获整个标识符。(如:
|| a.x + 1现在只捕获a.x而不是a)
- 数组
IntoIterator:array.into_iter() 现在按值,而不是按引用来迭代项目
- patterns 的
$_:pat 标识符在 macro_rules 宏里可以匹配 | (1.53 引入的 | 扩展 ),用 $_:pat_param 代替之前的 $_:pat ,$_:pat_param 不匹配 | ,但是可以在所有版本中使用。
- 默认用第二版 Cargo 。
- Prelude 库新增 :
TryInto 、 TryFrom 、 FromIterator 默认可用。
- Panic 宏只接受格式化字符串,比如
println!()
ident# 、ident"..." 和 ident'...' 变成保留语法。
bare_trait_objects 和 ellipsis_inclusive_range_patterns 从警告变成报错。
闭包的非联接捕获
新的不相交捕获功能可以简化编写闭包的过程,看个例子:
// 2015 或 2018 版代码
let a = SomeStruct::new();
// 从结构体的一个字段中移出drop(a.x);
// 还是使用结构体的另一个字段
println!("{}", a.y);
// 错误:在2021版之前,会试图捕获所有' a '
let c = || println!("{}", a.y);
c();
2021版本之前,你要在形成闭包之前手动提取相关的标识符,比如 let y = &a.y; ,从 Rust 2021 开始,闭包将自动捕获它们使用的字段,因此上面的示例可以正常编译。
Cargo rust-version
Cargo.toml 现在 支持 [package] rust-version 字段来指定 crate 支持的最低 Rust 版本,如果不满足,Cargo 将退出并显示早期错误。这不会影响依赖解析器,旨在解决兼容性的问题,避免编译的时候出现模糊不清的报错。
新绑定 binding @ pattern
Rust pattern 匹配可以用绑定值的单个标识符来编写,然后 @ 一个结构更精细的 pattern ,但现在还不允许进行额外的绑定。
struct Matrix {
data: Vec<f64>,
row_len: usize,
}
// 在此之前,我们需要单独的语句来绑定
let matrix = get_matrix();
let row_len = matrix.row_len;
// 或者使用一个破坏性的 pattern :
let Matrix { row_len, .. } = matrix;
// Rust 1.56 现在可以同时绑定两个
let matrix @ Matrix { row_len, .. } = get_matrix();
这个功能在 Rust 1.0 之前是可以用的,不过当时因为不完善而被删除了。随着版本的稳定,现在又可以使用了。
稳定的 API
以下方法和特征已稳定:
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.
std::mem::transmute
[T]::first
[T]::split_first
[T]::last
[T]::split_last
其他变化
Rust 1.56.0 版本中还有一些其他修改,详情请查看 Rust、 Cargo 和 Clippy 。