Rust 1.96.0 稳定版落地了。这次更新最值得动手试的是一套全新的 Range 类型——它们终于支持 Copy,迭代方式也从 Iterator 切换到了 IntoIterator。此外新增的断言匹配宏让测试中的结构化断言更简洁,Cargo 也修补了两个安全相关问题。下面逐项拆开看。
新 Range 类型:能 Copy 的区间抽象
旧版 Range(比如 0..10)有个长期痛点:它实现了 Iterator,但不支持 Copy。这意味着你把一个 range 传给函数后再想用它,就得重新构造,或者显式 clone。在需要反复使用同一区间的场景下,这既啰嗦又容易出错。
1.96.0 引入了 core::range 模块下的一组新类型:
| 新类型 | 对应旧语法 | 关键变化 |
|---|---|---|
core::range::Range |
a..b |
实现 Copy + IntoIterator |
core::range::RangeFrom |
a.. |
同上 |
core::range::RangeInclusive |
a..=b |
同上 |
core::range::RangeTo |
..b |
同上 |
core::range::RangeToInclusive |
..=b |
同上 |
核心区别:新类型实现 IntoIterator 而非直接实现 Iterator。这意味着类型本身不是迭代器,但可以通过 .into_iter() 产生迭代器。这一设计让类型本身保持轻量(可以 Copy),同时迭代行为仍然完整。
实际效果——同一个 range 可以反复使用,无需 clone:
use core::range::Range;
fn process(range: Range<usize>) -> usize {
// 第一次迭代
let sum = range.clone().into_iter().sum::<usize>();
// 第二次还能用——因为 Range 支持 Copy
let count = range.into_iter().count();
sum / count
}
fn main() {
let r = Range::new(1, 11); // 等价于旧版 1..11
println!("avg = {}", process(r));
// r 本身还能继续用,没有被消费
println!("range still valid: {:?}", r);
}
注意:
Range::new(start, end)的构造方式以及具体的 API 名称,请以 1.96.0 官方文档为准。上面示例展示的是Copy+IntoIterator的组合用法,实际方法名可能略有差异。升级后建议先cargo doc --open确认。
旧版 0..10 语法仍然可用,编译器会在适当场景下自动选择新类型。短期内你的既有代码不需要改动,但新代码中如果需要 Copy 行为,可以显式使用 core::range 模块下的类型。
断言匹配宏:测试里的结构化断言更清晰
测试中经常需要断言某个值"匹配某种结构"——比如枚举的特定变体、包含某些字段的结构体。以前只能用 matches! 配合 assert!,或者手动解构再断言,写起来分散且错误信息不友好。
1.96.0 新增的断言匹配宏(名称以 assert_ 开头,配合模式匹配)让你一步到位:断言通过时自动解构绑定,失败时输出结构化的差异信息。
#[derive(Debug)]
enum Event {
Login { user_id: u64 },
Logout(u64),
}
#[test]
fn test_event_match() {
let e = Event::Login { user_id: 42 };
// 新宏:匹配成功时绑定内部字段
assert_matches!(e, Event::Login { user_id } => {
assert_eq!(user_id, 42);
});
// 也可以只做模式断言,不绑定
assert_matches!(e, Event::Login { .. });
}
宏的具体名称和语法细节(是否为
assert_matches!或其他形式)以 1.96.0 发布说明为准。上面的示例展示了"匹配 + 绑定 + 内部断言"的典型用法思路。
对比旧写法:
// 旧写法:两步,错误信息不够结构化
assert!(matches!(e, Event::Login { user_id: 42 }));
新宏的优势在于:匹配失败时能告诉你哪个字段不匹配,而不是只抛一个布尔断言失败。
Cargo 安全更新:两个修复
本次还包含两个 Cargo 安全相关修复。虽然发布说明未完全展开细节,但根据 Rust 安全公告的历史模式,这类更新通常涉及:
- 依赖解析过程中的路径处理:防止恶意 crate 利用路径穿越或符号链接绕过限制。
- 凭证存储或网络传输:修补 token 泄露或未加密传输的边界情况。
升级 Cargo 本身就包含了这些修复,无需额外配置。如果你在 CI 中锁定了旧版 Rust 工具链,建议尽快更新。
升级命令:
# 使用 rustup 升级到 1.96.0
rustup update stable
# 确认版本
rustc --version
cargo --version
升级 checklist
| 项目 | 建议 |
|---|---|
| 工具链升级 | rustup update stable,CI 中同步更新镜像版本 |
| 新 Range 类型 | 新代码中需要 Copy 行为时,改用 core::range::*;旧代码无需改动 |
| 断言匹配宏 | 测试中替换 assert!(matches!(...)) 为新宏,获取更好的错误信息 |
| Cargo 安全修复 | 升级即生效,无需额外操作;检查是否有依赖锁定文件需要刷新 |
| edition 兼容性 | 新 Range 类型在旧 edition 下也可用(通过 core::range 路径),但部分语法糖可能需要 2024 edition |
Rust 的 Range 设计长期被 Copy 缺失困扰,这次的新类型体系是一次干净的解法——把"区间值"和"迭代行为"拆开,各归各的 trait。如果你的代码里有反复传递 range 的场景,1.96.0 值得马上升级试试。