Rust 1.96.0:可 Copy 的 Range 类型与断言匹配宏,还有两个 Cargo 安全修复

2026-05-29 19 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:7 分钟

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 值得马上升级试试。


相关推荐