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,原集合依然有四项。
文章回复
0 条公开回复