迭代器(Iterator)是 Rust 中用于处理元素序列的强大工具。迭代器模式允许你对一系列项进行某些操作,而无需手动管理索引或循环逻辑。Rust 的迭代器是惰性的(lazy),只在需要时才会执行计算,这使得它们既高效又灵活。
1. 迭代器基础
1.1 创建迭代器
在 Rust 中,所有集合类型都可以创建迭代器:
1 2 3 4 5 6 7 8 9 10 11
| fn main() { let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter { println!("值: {}", val); } }
|
1.2 三种迭代方法
Rust 提供三种获取迭代器的方法,它们在所有权处理上有所不同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| fn main() { let v = vec![1, 2, 3];
for val in v.iter() { println!("不可变引用: {}", val); }
let mut v_mut = vec![1, 2, 3]; for val in v_mut.iter_mut() { *val += 1; } println!("修改后: {:?}", v_mut);
for val in v.into_iter() { println!("获取所有权: {}", val); } }
|
2. Iterator Trait
2.1 Iterator trait 定义
所有迭代器都实现了 Iterator trait:
1 2 3 4 5 6 7
| pub trait Iterator { type Item;
fn next(&mut self) -> Option<Self::Item>;
}
|
2.2 手动调用 next 方法
1 2 3 4 5 6 7 8 9
| fn main() { let v1 = vec![1, 2, 3]; let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1)); assert_eq!(v1_iter.next(), Some(&2)); assert_eq!(v1_iter.next(), Some(&3)); assert_eq!(v1_iter.next(), None); }
|
注意:调用 next 需要 mut,因为迭代器内部状态会改变。
2.3 实现自定义迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| struct Counter { count: u32, }
impl Counter { fn new() -> Counter { Counter { count: 0 } } }
impl Iterator for Counter { type Item = u32;
fn next(&mut self) -> Option<Self::Item> { if self.count < 5 { self.count += 1; Some(self.count) } else { None } } }
fn main() { let mut counter = Counter::new();
assert_eq!(counter.next(), Some(1)); assert_eq!(counter.next(), Some(2)); assert_eq!(counter.next(), Some(3)); assert_eq!(counter.next(), Some(4)); assert_eq!(counter.next(), Some(5)); assert_eq!(counter.next(), None); }
|
3. 消费适配器(Consuming Adaptors)
消费适配器会调用 next 方法,消耗迭代器:
3.1 sum - 求和
1 2 3 4 5 6 7 8 9
| fn main() { let v1 = vec![1, 2, 3]; let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
println!("总和: {}", total); }
|
3.2 collect - 收集为集合
1 2 3 4 5 6 7
| fn main() { let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter().collect();
println!("收集结果: {:?}", v2); }
|
3.3 其他消费适配器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let count = numbers.iter().count(); println!("元素数量: {}", count);
let last = numbers.iter().last(); println!("最后元素: {:?}", last);
let max = numbers.iter().max(); let min = numbers.iter().min(); println!("最大值: {:?}, 最小值: {:?}", max, min); }
|
4. 迭代器适配器(Iterator Adaptors)
迭代器适配器会产生新的迭代器,它们是惰性的:
4.1 map - 映射转换
1 2 3 4 5 6 7 8 9 10
| fn main() { let v1: Vec<i32> = vec![1, 2, 3];
let v2: Vec<_> = v1.iter() .map(|x| x + 1) .collect();
println!("映射后: {:?}", v2); }
|
4.2 filter - 过滤元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #[derive(PartialEq, Debug)] struct Shoe { size: u32, style: String, }
fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> { shoes.into_iter() .filter(|s| s.size == shoe_size) .collect() }
fn main() { let shoes = vec![ Shoe { size: 10, style: String::from("运动鞋") }, Shoe { size: 13, style: String::from("凉鞋") }, Shoe { size: 10, style: String::from("靴子") }, ];
let in_my_size = shoes_in_size(shoes, 10);
println!("我的尺码: {:?}", in_my_size); }
|
4.3 常用迭代器适配器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let first_three: Vec<_> = numbers.iter() .take(3) .collect(); println!("前三个: {:?}", first_three);
let after_two: Vec<_> = numbers.iter() .skip(2) .collect(); println!("跳过两个: {:?}", after_two);
for (index, value) in numbers.iter().enumerate() { println!("索引 {}: 值 {}", index, value); }
let letters = vec!['a', 'b', 'c']; let zipped: Vec<_> = numbers.iter().zip(letters.iter()).collect(); println!("组合结果: {:?}", zipped); }
|
5. 链式调用
迭代器的强大之处在于可以链式调用多个方法:
5.1 复杂的数据处理
1 2 3 4 5 6 7 8 9 10
| fn main() { let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let result: i32 = numbers.iter() .filter(|&&x| x % 2 == 0) .map(|&x| x * x) .sum();
println!("偶数平方和: {}", result); }
|
5.2 字符串处理
1 2 3 4 5 6 7 8 9
| fn main() { let text = "hello world rust programming";
let long_words: Vec<&str> = text.split_whitespace() .filter(|word| word.len() > 5) .collect();
println!("长单词: {:?}", long_words); }
|
5.3 结构化数据处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #[derive(Debug)] struct Person { name: String, age: u32, }
fn main() { let people = vec![ Person { name: String::from("Alice"), age: 30 }, Person { name: String::from("Bob"), age: 25 }, Person { name: String::from("Charlie"), age: 35 }, ];
let names: Vec<String> = people.iter() .filter(|p| p.age > 28) .map(|p| p.name.clone()) .collect();
println!("年龄大于28的人: {:?}", names); }
|
6. 实用方法
6.1 find - 查找元素
1 2 3 4 5 6 7 8 9 10
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let first_even = numbers.iter().find(|&&x| x % 2 == 0);
match first_even { Some(&n) => println!("第一个偶数: {}", n), None => println!("没有偶数"), } }
|
6.2 any 和 all - 条件检查
1 2 3 4 5 6 7 8 9
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let has_even = numbers.iter().any(|&x| x % 2 == 0); println!("有偶数: {}", has_even);
let all_positive = numbers.iter().all(|&x| x > 0); println!("全是正数: {}", all_positive); }
|
6.3 fold - 累积计算
1 2 3 4 5 6 7 8 9 10
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let sum = numbers.iter().fold(0, |acc, &x| acc + x); println!("总和: {}", sum);
let product = numbers.iter().fold(1, |acc, &x| acc * x); println!("乘积: {}", product); }
|
6.4 flat_map - 扁平化映射
1 2 3 4 5 6 7 8 9
| fn main() { let words = vec!["hello", "world"];
let chars: Vec<char> = words.iter() .flat_map(|word| word.chars()) .collect();
println!("所有字符: {:?}", chars); }
|
7. 迭代器与性能
7.1 零成本抽象
Rust 的迭代器是零成本抽象,编译后的性能与手写循环相当:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| fn sum_iterator(numbers: &[i32]) -> i32 { numbers.iter().sum() }
fn sum_loop(numbers: &[i32]) -> i32 { let mut sum = 0; for &n in numbers { sum += n; } sum }
|
7.2 惰性求值的优势
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let iter = numbers.iter() .map(|x| { println!("映射 {}", x); x * 2 }) .filter(|x| { println!("过滤 {}", x); x > &5 });
println!("开始收集:"); let result: Vec<_> = iter.collect(); println!("结果: {:?}", result); }
|
8. 高级用法
8.1 组合多个迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| fn main() { let counter = Counter::new();
let sum: u32 = counter .zip(Counter::new().skip(1)) .map(|(a, b)| a * b) .filter(|x| x % 3 == 0) .sum();
println!("结果: {}", sum); }
struct Counter { count: u32, }
impl Counter { fn new() -> Counter { Counter { count: 0 } } }
impl Iterator for Counter { type Item = u32;
fn next(&mut self) -> Option<Self::Item> { if self.count < 5 { self.count += 1; Some(self.count) } else { None } } }
|
8.2 范围迭代器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| fn main() { for i in 0..5 { println!("{}", i); }
for i in (0..5).rev() { println!("{}", i); }
for i in (0..10).step_by(2) { println!("{}", i); } }
|
8.3 partition - 分区
1 2 3 4 5 6 7 8 9
| fn main() { let numbers = vec![1, 2, 3, 4, 5, 6];
let (evens, odds): (Vec<_>, Vec<_>) = numbers.into_iter() .partition(|&x| x % 2 == 0);
println!("偶数: {:?}", evens); println!("奇数: {:?}", odds); }
|
9. 常见陷阱与最佳实践
9.1 避免不必要的 collect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| fn sum_of_squares_bad(numbers: &[i32]) -> i32 { let squares: Vec<_> = numbers.iter() .map(|x| x * x) .collect(); squares.iter().sum() }
fn sum_of_squares_good(numbers: &[i32]) -> i32 { numbers.iter() .map(|x| x * x) .sum() }
fn main() { let numbers = vec![1, 2, 3, 4, 5]; println!("平方和: {}", sum_of_squares_good(&numbers)); }
|
9.2 注意迭代器的消费
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| fn main() { let v = vec![1, 2, 3]; let iter = v.iter();
let sum: i32 = v.iter().sum(); let count = v.iter().count();
println!("总和: {}, 数量: {}", sum, count); }
|
9.3 使用迭代器而非索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
for i in 0..numbers.len() { println!("{}", numbers[i]); }
for num in &numbers { println!("{}", num); }
for (index, num) in numbers.iter().enumerate() { println!("索引 {}: {}", index, num); } }
|
10. 实战案例
10.1 统计单词频率
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| use std::collections::HashMap;
fn word_frequency(text: &str) -> HashMap<String, usize> { text.split_whitespace() .map(|word| word.to_lowercase()) .fold(HashMap::new(), |mut map, word| { *map.entry(word).or_insert(0) += 1; map }) }
fn main() { let text = "Hello world hello Rust world"; let freq = word_frequency(text);
for (word, count) in freq { println!("{}: {}", word, count); } }
|
10.2 数据转换管道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #[derive(Debug)] struct Product { name: String, price: f64, category: String, }
fn main() { let products = vec![ Product { name: "笔记本".to_string(), price: 5000.0, category: "电子".to_string() }, Product { name: "鼠标".to_string(), price: 100.0, category: "电子".to_string() }, Product { name: "书籍".to_string(), price: 50.0, category: "图书".to_string() }, Product { name: "键盘".to_string(), price: 300.0, category: "电子".to_string() }, ];
let expensive_electronics: Vec<String> = products.iter() .filter(|p| p.category == "电子") .filter(|p| p.price > 200.0) .map(|p| p.name.clone()) .collect();
println!("昂贵的电子产品: {:?}", expensive_electronics); }
|
10.3 矩阵转置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| fn transpose(matrix: Vec<Vec<i32>>) -> Vec<Vec<i32>> { if matrix.is_empty() { return vec![]; }
let rows = matrix.len(); let cols = matrix[0].len();
(0..cols) .map(|col| { (0..rows) .map(|row| matrix[row][col]) .collect() }) .collect() }
fn main() { let matrix = vec![ vec![1, 2, 3], vec![4, 5, 6], ];
let transposed = transpose(matrix);
for row in transposed { println!("{:?}", row); } }
|
10.4 查找重复元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| use std::collections::HashSet;
fn find_duplicates(numbers: &[i32]) -> Vec<i32> { let mut seen = HashSet::new(); let mut duplicates = HashSet::new();
numbers.iter() .filter(|&&num| !seen.insert(num)) .for_each(|&num| { duplicates.insert(num); });
duplicates.into_iter().collect() }
fn main() { let numbers = vec![1, 2, 3, 2, 4, 5, 1, 6]; let dups = find_duplicates(&numbers);
println!("重复的元素: {:?}", dups); }
|
10.5 分组和聚合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| use std::collections::HashMap;
#[derive(Debug)] struct Sale { product: String, amount: f64, }
fn group_by_product(sales: Vec<Sale>) -> HashMap<String, f64> { sales.into_iter() .fold(HashMap::new(), |mut map, sale| { *map.entry(sale.product).or_insert(0.0) += sale.amount; map }) }
fn main() { let sales = vec![ Sale { product: "苹果".to_string(), amount: 100.0 }, Sale { product: "香蕉".to_string(), amount: 50.0 }, Sale { product: "苹果".to_string(), amount: 150.0 }, Sale { product: "橙子".to_string(), amount: 80.0 }, Sale { product: "香蕉".to_string(), amount: 30.0 }, ];
let totals = group_by_product(sales);
for (product, total) in totals { println!("{}: {:.2}", product, total); } }
|
11. 迭代器与错误处理
11.1 filter_map - 过滤和映射
1 2 3 4 5 6 7 8 9
| fn main() { let strings = vec!["1", "2", "three", "4", "5"];
let numbers: Vec<i32> = strings.iter() .filter_map(|s| s.parse().ok()) .collect();
println!("解析成功的数字: {:?}", numbers); }
|
11.2 处理 Result 序列
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| fn main() { let strings = vec!["1", "2", "three", "4"];
let result: Result<Vec<i32>, _> = strings.iter() .map(|s| s.parse::<i32>()) .collect();
match result { Ok(numbers) => println!("所有解析成功: {:?}", numbers), Err(e) => println!("解析失败: {}", e), }
let numbers: Vec<i32> = strings.iter() .filter_map(|s| s.parse().ok()) .collect();
println!("部分解析成功: {:?}", numbers); }
|
12. 性能优化技巧
12.1 使用 drain 避免复制
1 2 3 4 5 6 7 8 9
| fn main() { let mut v = vec![1, 2, 3, 4, 5];
let first_three: Vec<_> = v.drain(0..3).collect();
println!("提取的: {:?}", first_three); println!("剩余的: {:?}", v); }
|
12.2 避免重复计算
1 2 3 4 5 6 7 8 9 10 11 12 13
| fn main() { let numbers = vec![1, 2, 3, 4, 5];
let (sum, count) = numbers.iter() .fold((0, 0), |(sum, count), &x| (sum + x, count + 1));
println!("总和: {}, 数量: {}", sum, count); }
|
12.3 使用 by_ref 保留迭代器
1 2 3 4 5 6 7 8 9 10 11 12
| fn main() { let mut iter = vec![1, 2, 3, 4, 5].into_iter();
let first_two: Vec<_> = iter.by_ref().take(2).collect();
println!("前两个: {:?}", first_two);
let rest: Vec<_> = iter.collect(); println!("剩余的: {:?}", rest); }
|
总结
迭代器是 Rust 中处理序列数据的核心工具,掌握它能让你的代码更加:
- 简洁优雅:用链式调用替代复杂的循环逻辑
- 安全可靠:编译期保证类型安全,避免越界访问
- 高效性能:零成本抽象,编译后性能与手写循环相当
- 函数式风格:结合闭包实现声明式编程
- 可组合性:多个简单操作组合成复杂的数据处理管道
迭代器与闭包是 Rust 函数式编程的两大支柱,它们共同构成了 Rust 中优雅而高效的数据处理范式。熟练运用迭代器,是编写惯用 Rust 代码的必备技能。
Hooray!Iterators 小节完成!!!