Day 17: 迭代器
1. Iterator Trait 基础
Section titled “1. Iterator Trait 基础”迭代器是Rust中处理序列数据的强大工具。每个迭代器都实现了 Iterator trait:
trait Iterator { type Item; // 迭代器产生的元素类型
fn next(&mut self) -> Option<Self::Item>;
// 其他方法都有默认实现}fn main() { // 创建迭代器 let v = vec![1, 2, 3]; let mut iter = v.iter(); // 产生 &i32 引用
// 手动调用 next println!("{:?}", iter.next()); // Some(&1) println!("{:?}", iter.next()); // Some(&2) println!("{:?}", iter.next()); // Some(&3) println!("{:?}", iter.next()); // None
// 不同迭代器类型 let v = vec![1, 2, 3];
let iter_ref = v.iter(); // &T let iter_mut = v.iter_mut(); // &mut T let iter_into = v.into_iter(); // T (获取所有权)
let nums = vec![1, 2, 3]; for num in nums.iter() { println!("{}", num); }}2. Iterator Adaptors(迭代器适配器)
Section titled “2. Iterator Adaptors(迭代器适配器)”迭代器适配器将一个迭代器转换为另一个迭代器,是函数式编程的核心:
fn main() { let nums = vec![1, 2, 3, 4, 5];
// map: 转换每个元素 let doubled: Vec<_> = nums.iter().map(|x| x * 2).collect(); println!("doubled: {:?}", doubled);
// filter: 过滤元素 let evens: Vec<_> = nums.iter().filter(|x| *x % 2 == 0).collect(); println!("evens: {:?}", evens);
// filter_map: 同时过滤和转换 let strings = vec!["1", "two", "3", "four"]; let numbers: Vec<_> = strings .iter() .filter_map(|s| s.parse::<i32>().ok()) .collect(); println!("parsed: {:?}", numbers);
// take: 取前n个元素 let first_three: Vec<_> = nums.iter().take(3).collect(); println!("first three: {:?}", first_three);
// skip: 跳过前n个元素 let skip_two: Vec<_> = nums.iter().skip(2).collect(); println!("skip two: {:?}", skip_two);
// take_while: 取满足条件的元素 let less_than_4: Vec<_> = nums.iter().take_while(|x| **x < 4).collect(); println!("less than 4: {:?}", less_than_4);
// enumerate: 产生索引 let indexed: Vec<_> = nums.iter().enumerate().collect(); println!("indexed: {:?}", indexed);
// zip: 合并两个迭代器 let a = vec![1, 2, 3]; let b = vec!['a', 'b', 'c']; let zipped: Vec<_> = a.iter().zip(b.iter()).collect(); println!("zipped: {:?}", zipped);}3. fold 与 reduce
Section titled “3. fold 与 reduce”fold 和 reduce 用于将迭代器聚合成单个值:
fn main() { let nums = vec![1, 2, 3, 4, 5];
// fold: 初始值 + 累加器 let sum = nums.iter().fold(0, |acc, x| acc + x); println!("sum: {}", sum);
let product = nums.iter().fold(1, |acc, x| acc * x); println!("product: {}", product);
// 计算字符串长度 let words = vec!["hello", "world", "rust"]; let total_len = words.iter().fold(0, |acc, s| acc + s.len()); println!("total length: {}", total_len);
// 使用 fold 实现 map let doubled: Vec<_> = nums.iter().fold(Vec::new(), |mut acc, x| { acc.push(x * 2); acc }); println!("fold map: {:?}", doubled);
// reduce: 类似 fold,但使用第一个元素作为初始值 let nums2 = vec![1, 2, 3, 4, 5]; let sum2 = nums2.iter().copied().reduce(|acc, x| acc + x); println!("reduce sum: {:?}", sum2);
// 自定义累加结构 use std::collections::HashMap; let names = vec!["Alice", "Bob", "Alice", "Charlie", "Bob"]; let mut count: HashMap<&str, i32> = HashMap::new(); for name in &names { *count.entry(name).or_insert(0) += 1; } println!("name counts: {:?}", count);}4. 迭代器链式调用
Section titled “4. 迭代器链式调用”迭代器的强大之处在于可以链式调用多个适配器:
fn main() { let nums = (1..=100).collect::<Vec<_>>();
// 复杂的链式操作 let result = nums .iter() .filter(|&&x| x % 2 == 0) // 过滤偶数 .map(|x| x * x) // 平方 .filter(|&x| x < 1000) // 过滤小于1000 .take(10) // 取前10个 .fold(0, |acc, x| acc + x); // 求和
println!("result: {}", result);
// 查找满足条件的元素 let nums = vec![1, 3, 5, 7, 9, 11, 13]; let result = nums .iter() .find(|&&x| x > 5 && x < 10) .copied(); println!("find result: {:?}", result);
// 查找索引 let index = nums .iter() .position(|&x| x == 7) .copied(); println!("position of 7: {:?}", index);
// any 和 all let has_even = nums.iter().any(|&x| x % 2 == 0); let all_positive = nums.iter().all(|&x| x > 0); println!("has even: {}, all positive: {}", has_even, all_positive);
// partition: 按条件分割 let (evens, odds): (Vec<_>, Vec<_>) = nums .iter() .partition(|&x| x % 2 == 0); println!("evens: {:?}, odds: {:?}", evens, odds);}5. 迭代器性能
Section titled “5. 迭代器性能”Rust的迭代器是零成本抽象,编译后生成高效代码:
fn main() { // 迭代器版本的 sum fn sum_with_iter(nums: &[i32]) -> i32 { nums.iter().sum() }
// 手写循环版本 fn sum_with_loop(nums: &[i32]) -> i32 { let mut total = 0; for n in nums { total += *n; } total }
// 两种方式性能相当(编译器优化后) let nums: Vec<i32> = (1..=1000).collect(); println!("iter sum: {}", sum_with_iter(&nums)); println!("loop sum: {}", sum_with_loop(&nums));
// IntoIterator 实现 for 循环 let nums = vec![1, 2, 3]; for num in nums { // 这里 nums 被移动 println!("{}", num); }
// 使用 & 来避免移动 let nums = vec![1, 2, 3]; for num in &nums { println!("{}", num); }}6. 实现自定义迭代器
Section titled “6. 实现自定义迭代器”可以为自定义类型实现 Iterator trait:
struct Counter { count: u32, max: u32,}
impl Counter { fn new(max: u32) -> Counter { Counter { count: 0, max } }}
impl Iterator for Counter { type Item = u32;
fn next(&mut self) -> Option<Self::Item> { if self.count < self.max { self.count += 1; Some(self.count) } else { None } }}
fn main() { let counter = Counter::new(5);
let result: Vec<_> = counter.collect(); println!("Counter: {:?}", result);
// 可以在迭代器链中使用 let result: Vec<_> = Counter::new(5) .zip(Counter::new(5).skip(1)) .map(|(a, b)| a * b) .filter(|x| x % 3 == 0) .collect(); println!("zip + map + filter: {:?}", result);}今天我们深入学习了Rust迭代器:
- Iterator trait:
next()方法产生元素,返回Option<Self::Item> - 迭代器创建:
iter()、iter_mut()、into_iter() - 常用适配器:
map、filter、take、skip、zip、enumerate - 聚合操作:
fold、reduce、sum、collect - 链式调用:多个适配器组合实现复杂逻辑
- 零成本抽象:迭代器编译后生成高效代码
迭代器是Rust函数式编程的核心。明天我们将学习模块系统,理解Rust代码组织的最佳实践。