迭代器
学习目标
- 理解
Iteratortrait - 掌握
iter、into_iter、iter_mut的区别 - 掌握常用适配器和消费者
- 理解惰性求值
核心概念
Iterator trait
trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
// 其他方法有默认实现
}
三种迭代方式
fn main() {
let v = vec![1, 2, 3];
// iter(): 不可变借用 (&T)
for val in v.iter() {
println!("{}", val);
}
println!("v 仍可用: {:?}", v);
// into_iter(): 获取所有权 (T)
for val in v.into_iter() {
println!("{}", val);
}
// println!("{:?}", v); // ❌ 已被消耗
// iter_mut(): 可变借用 (&mut T)
let mut v = vec![1, 2, 3];
for val in v.iter_mut() {
*val *= 2;
}
println!("{:?}", v); // [2, 4, 6]
}
适配器(惰性)
fn main() {
let v = vec![1, 2, 3, 4, 5];
// map: 转换每个元素
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
// filter: 过滤元素
let evens: Vec<&i32> = v.iter().filter(|&&x| x % 2 == 0).collect();
// enumerate: 带索引
for (i, val) in v.iter().enumerate() {
println!("[{}] = {}", i, val);
}
// zip: 合并两个迭代器
let names = vec!["Alice", "Bob"];
let ages = vec![25, 30];
let people: Vec<_> = names.iter().zip(ages.iter()).collect();
// [("Alice", 25), ("Bob", 30)]
// chain: 连接
let a = vec![1, 2];
let b = vec![3, 4];
let combined: Vec<_> = a.iter().chain(b.iter()).collect();
// take / skip
let first_three: Vec<_> = v.iter().take(3).collect();
let skip_two: Vec<_> = v.iter().skip(2).collect();
}
消费者
fn main() {
let v = vec![1, 2, 3, 4, 5];
// collect: 收集到集合
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
// sum / product
let sum: i32 = v.iter().sum();
let product: i32 = v.iter().product();
// count / min / max
let count = v.iter().count();
let max = v.iter().max();
let min = v.iter().min();
// any / all
let has_even = v.iter().any(|&x| x % 2 == 0);
let all_positive = v.iter().all(|&x| x > 0);
// find
let first_even = v.iter().find(|&&x| x % 2 == 0);
// position
let pos = v.iter().position(|&x| x == 3);
// fold (reduce)
let sum = v.iter().fold(0, |acc, x| acc + x);
// for_each
v.iter().for_each(|x| print!("{} ", x));
}
自定义迭代器
struct Counter {
count: u32,
max: u32,
}
impl Counter {
fn new(max: u32) -> Self {
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 values: Vec<u32> = counter.collect();
println!("{:?}", values); // [1, 2, 3, 4, 5]
// 可以使用所有迭代器方法
let sum: u32 = Counter::new(5).sum();
println!("sum = {}", sum); // 15
let evens: Vec<u32> = Counter::new(10).filter(|x| x % 2 == 0).collect();
println!("evens = {:?}", evens); // [2, 4, 6, 8, 10]
}
实践练习
练习 1:单词计数
fn word_count(text: &str) -> std::collections::HashMap<String, usize> {
text.split_whitespace()
.map(|w| w.to_lowercase())
.fold(std::collections::HashMap::new(), |mut map, word| {
*map.entry(word).or_insert(0) += 1;
map
})
}
fn main() {
let text = "hello world hello rust hello world";
let counts = word_count(text);
let mut sorted: Vec<_> = counts.iter().collect();
sorted.sort_by(|a, b| b.1.cmp(a.1));
for (word, count) in sorted {
println!("{}: {}", word, count);
}
}
练习 2:矩阵展平
fn flatten(matrix: &Vec<Vec<i32>>) -> Vec<i32> {
matrix.iter().flat_map(|row| row.iter().copied()).collect()
}
fn main() {
let matrix = vec![
vec![1, 2, 3],
vec![4, 5, 6],
vec![7, 8, 9],
];
let flat = flatten(&matrix);
println!("{:?}", flat);
}
练习 3:斐波那契
struct Fibonacci {
a: u64,
b: u64,
}
impl Fibonacci {
fn new() -> Self {
Fibonacci { 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 fibs: Vec<u64> = Fibonacci::new().take(10).collect();
println!("{:?}", fibs);
}
常见错误
1. 忘记 collect
let v = vec![1, 2, 3];
let mapped = v.iter().map(|x| x * 2); // 这是惰性迭代器,不是 Vec
let mapped: Vec<_> = v.iter().map(|x| x * 2).collect(); // ✅
2. 迭代器已消耗
let v = vec![1, 2, 3];
let iter = v.iter();
let sum: i32 = iter.sum();
// let count = iter.count(); // ❌ iter 已被 sum 消耗
小结
| 方法 | 类型 | 说明 |
|---|---|---|
iter() | 适配器 | 不可变借用 |
into_iter() | 适配器 | 获取所有权 |
iter_mut() | 适配器 | 可变借用 |
map, filter | 适配器 | 惰性转换 |
collect, sum | 消费者 | 触发计算 |
take, skip | 适配器 | 限制数量 |
zip, chain | 适配器 | 组合迭代器 |
fold | 消费者 | 累积计算 |
练习编辑器
rust
Loading...