第14章:迭代器
第14章:迭代器
14.1 Iterator Trait
// 核心 trait 定义
// trait Iterator {
// type Item;
// fn next(&mut self) -> Option<Self::Item>;
// }
fn main() {
let v = vec![1, 2, 3];
// iter() 返回不可变引用迭代器
let mut iter = v.iter();
println!("{:?}", iter.next()); // Some(1)
println!("{:?}", iter.next()); // Some(2)
println!("{:?}", iter.next()); // Some(3)
println!("{:?}", iter.next()); // None
// into_iter() 获取所有权
for val in v.into_iter() {
print!("{} ", val);
}
println!();
// println!("{:?}", v); // ❌ v 已被消耗
// iter_mut() 返回可变引用迭代器
let mut v2 = vec![1, 2, 3];
for val in v2.iter_mut() {
*val *= 2;
}
println!("可变迭代后: {:?}", v2); // [2, 4, 6]
}
14.2 迭代器适配器
适配器(adaptor)将一个迭代器转换为另一个迭代器,惰性求值。
map
fn main() {
let v = vec![1, 2, 3, 4, 5];
// map: 转换每个元素
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
println!("map: {:?}", doubled); // [2, 4, 6, 8, 10]
}
filter / filter_map
fn main() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// filter: 保留满足条件的元素
let evens: Vec<&i32> = v.iter().filter(|&&x| x % 2 == 0).collect();
println!("filter: {:?}", evens); // [2, 4, 6, 8, 10]
// filter_map: filter + map 一步完成
let results: Vec<i32> = v
.iter()
.filter_map(|&x| {
if x % 2 == 0 { Some(x * x) } else { None }
})
.collect();
println!("filter_map: {:?}", results); // [4, 16, 36, 64, 100]
// 处理 Option/Result 集合
let strings = vec!["42", "abc", "7", "xyz", "13"];
let numbers: Vec<i32> = strings.iter().filter_map(|s| s.parse().ok()).collect();
println!("解析结果: {:?}", numbers); // [42, 7, 13]
}
flat_map
fn main() {
// flat_map: map + flatten
let sentences = vec!["hello world", "foo bar baz"];
let words: Vec<&str> = sentences.iter().flat_map(|s| s.split_whitespace()).collect();
println!("flat_map: {:?}", words);
// 嵌套展开
let nested = vec![vec![1, 2], vec![3, 4], vec![5]];
let flat: Vec<&i32> = nested.iter().flat_map(|v| v.iter()).collect();
println!("flat: {:?}", flat); // [1, 2, 3, 4, 5]
}
enumerate / zip
fn main() {
let v = vec!["a", "b", "c"];
// enumerate: 附加索引
for (i, val) in v.iter().enumerate() {
println!("{}: {}", i, val);
}
// zip: 合并两个迭代器
let names = vec!["Alice", "Bob", "Charlie"];
let scores = vec![95, 87, 92];
let pairs: Vec<_> = names.iter().zip(scores.iter()).collect();
println!("zip: {:?}", pairs);
// zip + collect 到 HashMap
let map: std::collections::HashMap<_, _> = names.into_iter().zip(scores.into_iter()).collect();
println!("HashMap: {:?}", map);
}
take / skip
fn main() {
let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// take: 取前 n 个
let first_three: Vec<&i32> = v.iter().take(3).collect();
println!("take(3): {:?}", first_three); // [1, 2, 3]
// skip: 跳过前 n 个
let skip_three: Vec<&i32> = v.iter().skip(3).collect();
println!("skip(3): {:?}", skip_three); // [4, 5, 6, 7, 8, 9, 10]
// take_while: 取直到条件不满足
let taken: Vec<&i32> = v.iter().take_while(|&&x| x < 5).collect();
println!("take_while(<5): {:?}", taken); // [1, 2, 3, 4]
// skip_while: 跳过直到条件不满足
let skipped: Vec<&i32> = v.iter().skip_while(|&&x| x < 5).collect();
println!("skip_while(<5): {:?}", skipped); // [5, 6, 7, 8, 9, 10]
}
chain / inspect / peekable
fn main() {
// chain: 连接两个迭代器
let a = vec![1, 2, 3];
let b = vec![4, 5, 6];
let chained: Vec<&i32> = a.iter().chain(b.iter()).collect();
println!("chain: {:?}", chained);
// inspect: 查看每个元素(不修改)
let result: Vec<i32> = (1..=5)
.inspect(|x| print!("观察{} ", x))
.map(|x| x * 2)
.collect();
println!("\n结果: {:?}", result);
// peekable: 可以预览下一个元素而不消费
let mut iter = (1..=5).peekable();
println!("peek: {:?}", iter.peek()); // Some(&1)
println!("next: {:?}", iter.next()); // Some(1)
println!("peek: {:?}", iter.peek()); // Some(&2)
}
14.3 消费者(Consumer)
消费者(consumer)消耗迭代器,产生最终结果。
collect
use std::collections::{HashMap, BTreeMap, HashSet};
fn main() {
let v = vec![1, 2, 3, 4, 5];
// collect 到 Vec
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
println!("Vec: {:?}", doubled);
// collect 到 String
let chars = vec!['h', 'e', 'l', 'l', 'o'];
let s: String = chars.into_iter().collect();
println!("String: {}", s);
// collect 到 Result(遇到第一个 Err 就停止)
let strings = vec!["1", "2", "3"];
let numbers: Result<Vec<i32>, _> = strings.iter().map(|s| s.parse::<i32>()).collect();
println!("Result<Vec>: {:?}", numbers);
// collect 到 HashMap
let pairs = vec![("a", 1), ("b", 2), ("c", 3)];
let map: HashMap<&str, i32> = pairs.into_iter().collect();
println!("HashMap: {:?}", map);
}
sum / product / count
fn main() {
let v = vec![1, 2, 3, 4, 5];
let sum: i32 = v.iter().sum();
println!("sum: {}", sum); // 15
let product: i32 = v.iter().product();
println!("product: {}", product); // 120
let count = v.iter().filter(|&&x| x > 3).count();
println!("count(>3): {}", count); // 2
}
min / max / min_by / max_by
fn main() {
let v = vec![3, 1, 4, 1, 5, 9, 2, 6];
println!("min: {:?}", v.iter().min()); // Some(1)
println!("max: {:?}", v.iter().max()); // Some(9)
// min_by_key / max_by_key
let words = vec!["hello", "hi", "hey", "greetings"];
let shortest = words.iter().min_by_key(|w| w.len());
let longest = words.iter().max_by_key(|w| w.len());
println!("最短: {:?}", shortest); // Some("hi")
println!("最长: {:?}", longest); // Some("greetings")
}
any / all
fn main() {
let v = vec![2, 4, 6, 8, 10];
// any: 是否存在满足条件的元素
println!("any > 5: {}", v.iter().any(|&x| x > 5)); // true
// all: 是否所有元素满足条件
println!("all even: {}", v.iter().all(|&x| x % 2 == 0)); // true
println!("all > 5: {}", v.iter().all(|&x| x > 5)); // false
}
find / position / fold
fn main() {
let v = vec![1, 2, 3, 4, 5];
// find: 查找第一个满足条件的元素
let first_even = v.iter().find(|&&x| x % 2 == 0);
println!("find even: {:?}", first_even); // Some(2)
// position: 查找索引
let pos = v.iter().position(|&x| x == 3);
println!("position of 3: {:?}", pos); // Some(2)
// fold: 归约
let sum = v.iter().fold(0, |acc, &x| acc + x);
println!("fold sum: {}", sum); // 15
// 复杂 fold
let result = (1..=5).fold(String::new(), |mut acc, x| {
acc.push_str(&format!("{} ", x));
acc
});
println!("fold string: {}", result);
}
14.4 自定义迭代器
struct Fibonacci {
a: u64,
b: u64,
}
impl Fibonacci {
fn new() -> Self {
Self { a: 0, b: 1 }
}
}
impl Iterator for Fibonacci {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
let result = self.a;
let new_b = self.a + self.b;
self.a = self.b;
self.b = new_b;
Some(result)
}
}
fn main() {
// 使用自定义迭代器
let fib: Vec<u64> = Fibonacci::new().take(15).collect();
println!("斐波那契: {:?}", fib);
// 与其他迭代器适配器组合
let even_fibs: Vec<u64> = Fibonacci::new()
.take(20)
.filter(|x| x % 2 == 0)
.collect();
println!("偶数斐波那契: {:?}", even_fibs);
// 求前 20 项之和
let sum: u64 = Fibonacci::new().take(20).sum();
println!("前20项和: {}", sum);
}
Range 自定义迭代器
struct StepRange {
current: i32,
end: i32,
step: i32,
}
impl StepRange {
fn new(start: i32, end: i32, step: i32) -> Self {
Self { current: start, end, step }
}
}
impl Iterator for StepRange {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if (self.step > 0 && self.current < self.end) ||
(self.step < 0 && self.current > self.end) {
let result = self.current;
self.current += self.step;
Some(result)
} else {
None
}
}
}
fn main() {
let range: Vec<i32> = StepRange::new(0, 20, 3).collect();
println!("步长3: {:?}", range); // [0, 3, 6, 9, 12, 15, 18]
let reverse: Vec<i32> = StepRange::new(10, 0, -2).collect();
println!("反向步长2: {:?}", reverse); // [10, 8, 6, 4, 2]
}
14.5 迭代器 vs 循环
性能对比
fn main() {
let v: Vec<i32> = (1..=1000).collect();
// 迭代器风格
let sum1: i32 = v.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * x)
.sum();
// 循环风格
let mut sum2 = 0i32;
for &x in &v {
if x % 2 == 0 {
sum2 += x * x;
}
}
println!("迭代器: {}", sum1);
println!("循环: {}", sum2);
println!("结果相同: {}", sum1 == sum2);
// 两种方式编译后生成的机器码几乎完全相同
// 迭代器是零成本抽象
}
14.6 业务场景示例
CSV 数据处理
#[derive(Debug)]
struct Record {
name: String,
score: f64,
}
fn parse_csv(input: &str) -> Vec<Record> {
input
.lines()
.skip(1) // 跳过表头
.filter(|line| !line.trim().is_empty())
.filter_map(|line| {
let parts: Vec<&str> = line.split(',').collect();
if parts.len() >= 2 {
let name = parts[0].trim().to_string();
let score: f64 = parts[1].trim().parse().ok()?;
Some(Record { name, score })
} else {
None
}
})
.collect()
}
fn analyze(records: &[Record]) {
let count = records.len();
let sum: f64 = records.iter().map(|r| r.score).sum();
let avg = sum / count as f64;
let max = records.iter().max_by(|a, b| a.score.partial_cmp(&b.score).unwrap());
let min = records.iter().min_by(|a, b| a.score.partial_cmp(&b.score).unwrap());
let above_avg: Vec<&str> = records
.iter()
.filter(|r| r.score > avg)
.map(|r| r.name.as_str())
.collect();
println!("统计结果:");
println!(" 总人数: {}", count);
println!(" 平均分: {:.1}", avg);
println!(" 最高分: {} ({:.1})", max.unwrap().name, max.unwrap().score);
println!(" 最低分: {} ({:.1})", min.unwrap().name, min.unwrap().score);
println!(" 高于平均: {:?}", above_avg);
}
fn main() {
let csv_data = "name,score\n\
Alice,95\n\
Bob,87\n\
Charlie,92\n\
David,78\n\
Eve,96\n\
Frank,88";
let records = parse_csv(csv_data);
analyze(&records);
}
14.7 本章小结
| 要点 | 说明 |
|---|---|
| Iterator trait | 实现 next() 方法即可创建迭代器 |
| 适配器 | map、filter、zip 等,惰性求值 |
| 消费者 | collect、sum、fold 等,消耗迭代器 |
| 自定义迭代器 | 为类型实现 Iterator trait |
| 零成本 | 迭代器性能与手写循环相同 |
扩展阅读
- Rust Book - 迭代器 — 官方教程
- Iterator 文档 — 完整 API 参考
- itertools crate — 更多迭代器适配器