强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Rust 系统编程语言完全教程 / 第14章:迭代器

第14章:迭代器

14.1 Iterator Trait

// 核心 trait 定义
// trait Iterator {
//     type Item;
//     fn next(&mut self) -> Option<Self::Item>;
// }

fn main() {
    let v = vec![1, 2, 3];

    // iter() 返回不可变引用迭代器
    let mut iter = v.iter();
    println!("{:?}", iter.next()); // Some(1)
    println!("{:?}", iter.next()); // Some(2)
    println!("{:?}", iter.next()); // Some(3)
    println!("{:?}", iter.next()); // None

    // into_iter() 获取所有权
    for val in v.into_iter() {
        print!("{} ", val);
    }
    println!();
    // println!("{:?}", v); // ❌ v 已被消耗

    // iter_mut() 返回可变引用迭代器
    let mut v2 = vec![1, 2, 3];
    for val in v2.iter_mut() {
        *val *= 2;
    }
    println!("可变迭代后: {:?}", v2); // [2, 4, 6]
}

14.2 迭代器适配器

适配器(adaptor)将一个迭代器转换为另一个迭代器,惰性求值。

map

fn main() {
    let v = vec![1, 2, 3, 4, 5];

    // map: 转换每个元素
    let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
    println!("map: {:?}", doubled); // [2, 4, 6, 8, 10]
}

filter / filter_map

fn main() {
    let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // filter: 保留满足条件的元素
    let evens: Vec<&i32> = v.iter().filter(|&&x| x % 2 == 0).collect();
    println!("filter: {:?}", evens); // [2, 4, 6, 8, 10]

    // filter_map: filter + map 一步完成
    let results: Vec<i32> = v
        .iter()
        .filter_map(|&x| {
            if x % 2 == 0 { Some(x * x) } else { None }
        })
        .collect();
    println!("filter_map: {:?}", results); // [4, 16, 36, 64, 100]

    // 处理 Option/Result 集合
    let strings = vec!["42", "abc", "7", "xyz", "13"];
    let numbers: Vec<i32> = strings.iter().filter_map(|s| s.parse().ok()).collect();
    println!("解析结果: {:?}", numbers); // [42, 7, 13]
}

flat_map

fn main() {
    // flat_map: map + flatten
    let sentences = vec!["hello world", "foo bar baz"];
    let words: Vec<&str> = sentences.iter().flat_map(|s| s.split_whitespace()).collect();
    println!("flat_map: {:?}", words);

    // 嵌套展开
    let nested = vec![vec![1, 2], vec![3, 4], vec![5]];
    let flat: Vec<&i32> = nested.iter().flat_map(|v| v.iter()).collect();
    println!("flat: {:?}", flat); // [1, 2, 3, 4, 5]
}

enumerate / zip

fn main() {
    let v = vec!["a", "b", "c"];

    // enumerate: 附加索引
    for (i, val) in v.iter().enumerate() {
        println!("{}: {}", i, val);
    }

    // zip: 合并两个迭代器
    let names = vec!["Alice", "Bob", "Charlie"];
    let scores = vec![95, 87, 92];
    let pairs: Vec<_> = names.iter().zip(scores.iter()).collect();
    println!("zip: {:?}", pairs);

    // zip + collect 到 HashMap
    let map: std::collections::HashMap<_, _> = names.into_iter().zip(scores.into_iter()).collect();
    println!("HashMap: {:?}", map);
}

take / skip

fn main() {
    let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    // take: 取前 n 个
    let first_three: Vec<&i32> = v.iter().take(3).collect();
    println!("take(3): {:?}", first_three); // [1, 2, 3]

    // skip: 跳过前 n 个
    let skip_three: Vec<&i32> = v.iter().skip(3).collect();
    println!("skip(3): {:?}", skip_three); // [4, 5, 6, 7, 8, 9, 10]

    // take_while: 取直到条件不满足
    let taken: Vec<&i32> = v.iter().take_while(|&&x| x < 5).collect();
    println!("take_while(<5): {:?}", taken); // [1, 2, 3, 4]

    // skip_while: 跳过直到条件不满足
    let skipped: Vec<&i32> = v.iter().skip_while(|&&x| x < 5).collect();
    println!("skip_while(<5): {:?}", skipped); // [5, 6, 7, 8, 9, 10]
}

chain / inspect / peekable

fn main() {
    // chain: 连接两个迭代器
    let a = vec![1, 2, 3];
    let b = vec![4, 5, 6];
    let chained: Vec<&i32> = a.iter().chain(b.iter()).collect();
    println!("chain: {:?}", chained);

    // inspect: 查看每个元素(不修改)
    let result: Vec<i32> = (1..=5)
        .inspect(|x| print!("观察{} ", x))
        .map(|x| x * 2)
        .collect();
    println!("\n结果: {:?}", result);

    // peekable: 可以预览下一个元素而不消费
    let mut iter = (1..=5).peekable();
    println!("peek: {:?}", iter.peek());     // Some(&1)
    println!("next: {:?}", iter.next());     // Some(1)
    println!("peek: {:?}", iter.peek());     // Some(&2)
}

14.3 消费者(Consumer)

消费者(consumer)消耗迭代器,产生最终结果。

collect

use std::collections::{HashMap, BTreeMap, HashSet};

fn main() {
    let v = vec![1, 2, 3, 4, 5];

    // collect 到 Vec
    let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
    println!("Vec: {:?}", doubled);

    // collect 到 String
    let chars = vec!['h', 'e', 'l', 'l', 'o'];
    let s: String = chars.into_iter().collect();
    println!("String: {}", s);

    // collect 到 Result(遇到第一个 Err 就停止)
    let strings = vec!["1", "2", "3"];
    let numbers: Result<Vec<i32>, _> = strings.iter().map(|s| s.parse::<i32>()).collect();
    println!("Result<Vec>: {:?}", numbers);

    // collect 到 HashMap
    let pairs = vec![("a", 1), ("b", 2), ("c", 3)];
    let map: HashMap<&str, i32> = pairs.into_iter().collect();
    println!("HashMap: {:?}", map);
}

sum / product / count

fn main() {
    let v = vec![1, 2, 3, 4, 5];

    let sum: i32 = v.iter().sum();
    println!("sum: {}", sum); // 15

    let product: i32 = v.iter().product();
    println!("product: {}", product); // 120

    let count = v.iter().filter(|&&x| x > 3).count();
    println!("count(>3): {}", count); // 2
}

min / max / min_by / max_by

fn main() {
    let v = vec![3, 1, 4, 1, 5, 9, 2, 6];

    println!("min: {:?}", v.iter().min());           // Some(1)
    println!("max: {:?}", v.iter().max());           // Some(9)

    // min_by_key / max_by_key
    let words = vec!["hello", "hi", "hey", "greetings"];
    let shortest = words.iter().min_by_key(|w| w.len());
    let longest = words.iter().max_by_key(|w| w.len());
    println!("最短: {:?}", shortest); // Some("hi")
    println!("最长: {:?}", longest);  // Some("greetings")
}

any / all

fn main() {
    let v = vec![2, 4, 6, 8, 10];

    // any: 是否存在满足条件的元素
    println!("any > 5: {}", v.iter().any(|&x| x > 5));  // true

    // all: 是否所有元素满足条件
    println!("all even: {}", v.iter().all(|&x| x % 2 == 0)); // true
    println!("all > 5: {}", v.iter().all(|&x| x > 5));       // false
}

find / position / fold

fn main() {
    let v = vec![1, 2, 3, 4, 5];

    // find: 查找第一个满足条件的元素
    let first_even = v.iter().find(|&&x| x % 2 == 0);
    println!("find even: {:?}", first_even); // Some(2)

    // position: 查找索引
    let pos = v.iter().position(|&x| x == 3);
    println!("position of 3: {:?}", pos); // Some(2)

    // fold: 归约
    let sum = v.iter().fold(0, |acc, &x| acc + x);
    println!("fold sum: {}", sum); // 15

    // 复杂 fold
    let result = (1..=5).fold(String::new(), |mut acc, x| {
        acc.push_str(&format!("{} ", x));
        acc
    });
    println!("fold string: {}", result);
}

14.4 自定义迭代器

struct Fibonacci {
    a: u64,
    b: u64,
}

impl Fibonacci {
    fn new() -> Self {
        Self { 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 fib: Vec<u64> = Fibonacci::new().take(15).collect();
    println!("斐波那契: {:?}", fib);

    // 与其他迭代器适配器组合
    let even_fibs: Vec<u64> = Fibonacci::new()
        .take(20)
        .filter(|x| x % 2 == 0)
        .collect();
    println!("偶数斐波那契: {:?}", even_fibs);

    // 求前 20 项之和
    let sum: u64 = Fibonacci::new().take(20).sum();
    println!("前20项和: {}", sum);
}

Range 自定义迭代器

struct StepRange {
    current: i32,
    end: i32,
    step: i32,
}

impl StepRange {
    fn new(start: i32, end: i32, step: i32) -> Self {
        Self { current: start, end, step }
    }
}

impl Iterator for StepRange {
    type Item = i32;

    fn next(&mut self) -> Option<Self::Item> {
        if (self.step > 0 && self.current < self.end) ||
           (self.step < 0 && self.current > self.end) {
            let result = self.current;
            self.current += self.step;
            Some(result)
        } else {
            None
        }
    }
}

fn main() {
    let range: Vec<i32> = StepRange::new(0, 20, 3).collect();
    println!("步长3: {:?}", range); // [0, 3, 6, 9, 12, 15, 18]

    let reverse: Vec<i32> = StepRange::new(10, 0, -2).collect();
    println!("反向步长2: {:?}", reverse); // [10, 8, 6, 4, 2]
}

14.5 迭代器 vs 循环

性能对比

fn main() {
    let v: Vec<i32> = (1..=1000).collect();

    // 迭代器风格
    let sum1: i32 = v.iter()
        .filter(|&&x| x % 2 == 0)
        .map(|&x| x * x)
        .sum();

    // 循环风格
    let mut sum2 = 0i32;
    for &x in &v {
        if x % 2 == 0 {
            sum2 += x * x;
        }
    }

    println!("迭代器: {}", sum1);
    println!("循环:   {}", sum2);
    println!("结果相同: {}", sum1 == sum2);

    // 两种方式编译后生成的机器码几乎完全相同
    // 迭代器是零成本抽象
}

14.6 业务场景示例

CSV 数据处理

#[derive(Debug)]
struct Record {
    name: String,
    score: f64,
}

fn parse_csv(input: &str) -> Vec<Record> {
    input
        .lines()
        .skip(1) // 跳过表头
        .filter(|line| !line.trim().is_empty())
        .filter_map(|line| {
            let parts: Vec<&str> = line.split(',').collect();
            if parts.len() >= 2 {
                let name = parts[0].trim().to_string();
                let score: f64 = parts[1].trim().parse().ok()?;
                Some(Record { name, score })
            } else {
                None
            }
        })
        .collect()
}

fn analyze(records: &[Record]) {
    let count = records.len();
    let sum: f64 = records.iter().map(|r| r.score).sum();
    let avg = sum / count as f64;

    let max = records.iter().max_by(|a, b| a.score.partial_cmp(&b.score).unwrap());
    let min = records.iter().min_by(|a, b| a.score.partial_cmp(&b.score).unwrap());

    let above_avg: Vec<&str> = records
        .iter()
        .filter(|r| r.score > avg)
        .map(|r| r.name.as_str())
        .collect();

    println!("统计结果:");
    println!("  总人数: {}", count);
    println!("  平均分: {:.1}", avg);
    println!("  最高分: {} ({:.1})", max.unwrap().name, max.unwrap().score);
    println!("  最低分: {} ({:.1})", min.unwrap().name, min.unwrap().score);
    println!("  高于平均: {:?}", above_avg);
}

fn main() {
    let csv_data = "name,score\n\
                    Alice,95\n\
                    Bob,87\n\
                    Charlie,92\n\
                    David,78\n\
                    Eve,96\n\
                    Frank,88";

    let records = parse_csv(csv_data);
    analyze(&records);
}

14.7 本章小结

要点说明
Iterator trait实现 next() 方法即可创建迭代器
适配器map、filter、zip 等,惰性求值
消费者collect、sum、fold 等,消耗迭代器
自定义迭代器为类型实现 Iterator trait
零成本迭代器性能与手写循环相同

扩展阅读

  1. Rust Book - 迭代器 — 官方教程
  2. Iterator 文档 — 完整 API 参考
  3. itertools crate — 更多迭代器适配器