25·函数式编程进阶

迭代器

迭代器

学习目标

  1. 理解 Iterator trait
  2. 掌握 iterinto_iteriter_mut 的区别
  3. 掌握常用适配器和消费者
  4. 理解惰性求值

核心概念

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...