DevCN
菜单
全部文章快讯开发科技深度热点

Rust 迭代器:筛选时长并保留原始集合

组合 iter、copied、filter 与 sum 完成有效分钟数统计,理解闭包接收的引用层次和读取后仍可使用原 vector 的原因。


本节目标

组合 iter、copied、filter 与 sum 完成有效分钟数统计,理解闭包接收的引用层次和读取后仍可使用原 vector 的原因。

环境与运行方法

保存为 lesson.rs,使用 Rust 工具链执行 rustc --edition=2021 lesson.rs -o lesson,然后运行 ./lesson。代码也可放进 Cargo 项目的 src/main.rs。

核心思路

iter 借用容器,copied 对 i32 复制值,filter 根据条件筛选,sum 完成累计。显式指定结果为 i32,让编译器知道如何求和。处理链不消费原容器。

完整示例

fn main() {
    let records = vec![20, -5, 35, 0];
    let total: i32 = records.iter().copied().filter(|n| *n >= 0).sum();
    let count = records.iter().filter(|n| **n >= 0).count();
    println!("valid={} total={}", count, total);
    println!("original={}", records.len());
}

预期输出

valid=3 total=55
original=4

逐步理解

第一条链 copied 后的元素是整数,但 filter 的条件闭包借用当前元素,所以用一次解引用。第二条链当前元素本来就是引用,因此需要两次解引用。先理解元素类型,再解释星号数量。

这两次统计分别遍历集合,便于阅读。若数据量很大且需要一次完成多个累计,可以使用 fold,但不应在尚未发现瓶颈时牺牲清晰度。零分钟保留,负值过滤。

常见问题与边界

  • into_iter 可能消费容器,与 iter 不同。
  • 把 >=0 写成 >0 会改变有效记录定义。
  • i32 也可能溢出,真实累计规模需要单独评估。

动手练习

用空集合运行,再把 -5 改为 5。

参考答案

空集合得到 valid=0 total=0 和 original=0。改成 5 后四项都有效,总和 60,原集合依然有四项。

DISCUSSION

文章回复

0 条公开回复
未登录回复需要审核后公开
还没有回复,欢迎参与讨论。