Rust 发布 1.56.0 版本,支持闭包非联接捕获
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::chrootUnsafeCell::raw_getBufWriter::into_partscore::panic::{UnwindSafe, RefUnwindSafe, AssertUnwindSafe}(以前只在std里支持)Vec::shrink_toString::shrink_toOsString::shrink_toPathBuf::shrink_toBinaryHeap::shrink_toVecDeque::shrink_toHashMap::shrink_toHashSet::shrink_to
下面这些之前稳定的函数现在属于 const.
std::mem::transmute[T]::first[T]::split_first[T]::last[T]::split_last