Skip to content

Day 17: 迭代器

迭代器是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);
}

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);
}

迭代器的强大之处在于可以链式调用多个适配器:

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);
}

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);
}
}

可以为自定义类型实现 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代码组织的最佳实践。