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()
现在按值而不是按引用迭代项目。 - 宏规则中的或模式 现在匹配
:pat
中的顶层A|B
。 - 默认 Cargo 特性解析器 现在是版本 2。
- 对序言的添加:
TryInto
、TryFrom
和FromIterator
现在默认在作用域内。 - 恐慌宏 现在始终需要格式字符串,就像
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
字段,以指定箱子的最小支持 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
以下方法和特征实现已稳定。
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 版。没有你们,我们无法做到。 感谢!