迭代器高级特性
> 掌握惰性求值的高级用法,学会实现自定义迭代器。
惰性求值
惰性求值演示
rust
▶ Runfn main() {
let numbers = vec![1, 2, 3, 4, 5];
// 惰性:创建迭代器时不执行
let result = numbers
.iter()
.map(|x| {
println!("Processing {}", x);
x * 2
})
.filter(|x| *x > 4);
// 此时还没有执行任何操作
println!("迭代器已创建,但尚未执行\n");
// 消费时才执行
for i in result {
println!("Got: {}", i);
}
}输出:
迭代器已创建,但尚未执行
Processing 1
Processing 2
Got: 6
Processing 3
Got: 8
Processing 4
Got: 10
Processing 5惰性求值的优势
rust
▶ Runfn main() {
// 优势 1:短路求值
let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// find 找到第一个匹配就停止
let found = numbers.iter().find(|&&x| {
println!("检查 {}", x);
x > 5
});
println!("找到:{:?}\n", found);
// 优势 2:无限序列
let powers_of_2 = std::iter::successors(Some(1), |&n| Some(n * 2));
// 只取前 10 个,不会无限循环
let first_10: Vec<_> = powers_of_2.take(10).collect();
println!("前 10 个 2 的幂:{:?}\n", first_10);
// 优势 3:组合优化
let result: Vec<_> = numbers
.iter()
.filter(|&x| {
println!("filter: {}", x);
x % 2 == 0
})
.map(|x| {
println!("map: {}", x);
x * 2
})
.take(2) // 只取 2 个,前面的操作也会相应减少执行
.collect();
println!("结果:{:?}", result);
}自定义迭代器
实现 Iterator Trait
rust
▶ Run/// 计数器迭代器
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 {
let result = self.count;
self.count += 1;
Some(result)
} else {
None
}
}
}
fn main() {
// 使用自定义迭代器
let counter = Counter::new(5);
println!("使用 for 循环:");
for i in counter {
println!(" {}", i);
}
// 可以使用迭代器方法
let counter = Counter::new(5);
let sum: u32 = counter.sum();
println!("总和:{}", sum); // 0+1+2+3+4 = 10
let counter = Counter::new(5);
let collected: Vec<u32> = counter.collect();
println!("收集:{:?}", collected); // [0, 1, 2, 3, 4]
}斐波那契数列迭代器
rust
▶ Run/// 斐波那契迭代器
struct Fibonacci {
current: u64,
next: u64,
}
impl Fibonacci {
fn new() -> Fibonacci {
Fibonacci { current: 0, next: 1 }
}
}
impl Iterator for Fibonacci {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
let new_current = self.current + self.next;
self.current = self.next;
self.next = new_current;
Some(self.current)
}
}
fn main() {
let fib = Fibonacci::new();
// 前 10 个斐波那契数
println!("前 10 个斐波那契数:");
for n in fib.take(10) {
print!("{} ", n);
}
println!("\n");
// 小于 100 的斐波那契数
println!("小于 100 的斐波那契数:");
let under_100: Vec<_> = Fibonacci::new()
.take_while(|&n| n < 100)
.collect();
println!("{:?}", under_100);
// 第 20 个斐波那契数
let twentieth = Fibonacci::new().nth(19);
println!("第 20 个斐波那契数:{:?}", twentieth);
}范围迭代器
rust
▶ Run/// 自定义范围迭代器(包含结束值)
struct InclusiveRange {
start: u32,
end: u32,
}
impl InclusiveRange {
fn new(start: u32, end: u32) -> Self {
InclusiveRange { start, end }
}
}
impl Iterator for InclusiveRange {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
if self.start <= self.end {
let result = self.start;
self.start += 1;
Some(result)
} else {
None
}
}
}
fn main() {
let range = InclusiveRange::new(1, 5);
let collected: Vec<u32> = range.collect();
println!("包含结束值:{:?}", collected); // [1, 2, 3, 4, 5]
// 与标准库 range 对比
let standard: Vec<u32> = (1..5).collect();
println!("标准范围:{:?}", standard); // [1, 2, 3, 4]
let standard_inclusive: Vec<u32> = (1..=5).collect();
println!("标准包含:{:?}", standard_inclusive); // [1, 2, 3, 4, 5]
}
---
## 小结
- 惰性求值在消费时才执行,支持短路操作
- 短路操作 find、any、all 提高效率
- 自定义迭代器只需实现 Iterator trait 的 next 方法
- 迭代器可以处理无限序列(配合 take 使用)
- 斐波那契数列是自定义迭代器的经典示例
## 练习题
详见:[练习题](../../exercises/19-iterators)