Skip to content

迭代器高级特性

> 掌握惰性求值的高级用法,学会实现自定义迭代器。

惰性求值

惰性求值演示

rust
fn 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);
    }
}
▶ Run

输出:

迭代器已创建,但尚未执行

Processing 1
Processing 2
Got: 6
Processing 3
Got: 8
Processing 4
Got: 10
Processing 5

惰性求值的优势

rust
fn 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);
}
▶ Run

自定义迭代器

实现 Iterator Trait

rust
/// 计数器迭代器
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]
}
▶ Run

斐波那契数列迭代器

rust
/// 斐波那契迭代器
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);
}
▶ Run

范围迭代器

rust
/// 自定义范围迭代器(包含结束值)
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)
▶ Run