什么是 Rust 迭代器?

Rust 的迭代器(Iterator)是一种强大的抽象,它允许你遍历集合元素而不需要关心底层数据结构的具体实现。迭代器模式是函数式编程的核心概念之一,Rust 在这方面做得特别出色。

迭代器的基本概念

在 Rust 中,任何实现了 Iterator trait 的类型都可以称为迭代器:

pub trait Iterator {
    type Item;
    fn next(&mut self) -> Option<Self::Item>;
}

核心方法 next() 返回 Option<Item>,当迭代完成时返回 None

创建迭代器的方法

1. iter() - 不可变引用迭代

fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    
    // 使用 iter() 创建迭代器
    let mut iter = vec.iter();
    
    assert_eq!(iter.next(), Some(&1));
    assert_eq!(iter.next(), Some(&2));
    assert_eq!(iter.next(), Some(&3));
    assert_eq!(iter.next(), Some(&4));
    assert_eq!(iter.next(), Some(&5));
    assert_eq!(iter.next(), None);
}

2. iter_mut() - 可变引用迭代

fn main() {
    let mut vec = vec![1, 2, 3, 4, 5];
    
    // 使用 iter_mut() 创建可变迭代器
    for item in vec.iter_mut() {
        *item *= 2;
    }
    
    assert_eq!(vec, vec![2, 4, 6, 8, 10]);
}

3. into_iter() - 获取所有权迭代

fn main() {
    let vec = vec![1, 2, 3, 4, 5];
    
    // 使用 into_iter() 消耗原集合
    let sum: i32 = vec.into_iter().sum();
    
    // 此时 vec 已被移动,无法再使用
    // println!("{:?}", vec); // 编译错误!
    
    assert_eq!(sum, 15);
}

常用迭代器方法详解

1. map() - 转换元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 将每个元素乘以 2
    // map() 接收一个闭包作为参数:
    // |x| x * 2
    // - x: 对迭代器中每个元素的引用
    // - 返回值: 转换后的新元素
    // - 注意:这里 x 是 &i32 类型,乘法会自动解引用
    let doubled: Vec<i32> = numbers.iter()
        .map(|x| x * 2)
        .collect();
    
    assert_eq!(doubled, vec![2, 4, 6, 8, 10]);
    
    // 复杂转换:将数字格式化为字符串
    // 闭包参数 |x| 中的 x 是 &i32
    // format! 宏将数字转换为 String
    let strings: Vec<String> = numbers.iter()
        .map(|x| format!("Number: {}", x))
        .collect();
    
    assert_eq!(strings, vec!["Number: 1", "Number: 2", "Number: 3", "Number: 4", "Number: 5"]);
}

2. filter() - 过滤元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 过滤偶数
    // filter() 接收一个返回 bool 的闭包作为参数:
    // |&x| x % 2 == 0
    // - &x: 对每个元素的引用解构,x 是 i32 类型
    // - 返回值: bool,true 表示保留该元素,false 表示丢弃
    // - 注意:|&x| 是 |x| *x 的语法糖,用于解构引用
    let evens: Vec<i32> = numbers.iter()
        .filter(|&x| x % 2 == 0)
        .copied() // 将 &i32 转换为 i32
        .collect();
    
    assert_eq!(evens, vec![2, 4, 6, 8, 10]);
    
    // 过滤长度大于 3 的字符串
    // filter() 接收闭包 |word| word.len() > 3
    // - word: &str 类型,对字符串切片的引用
    // - 返回值: bool,判断字符串长度是否大于 3
    let words = vec!["a", "the", "is", "rust", "code"];
    let long_words: Vec<&str> = words.iter()
        .filter(|word| word.len() > 3)
        .copied()
        .collect();
    
    assert_eq!(long_words, vec!["rust", "code"]);
}

3. filter_map() - 过滤并转换

fn main() {
    let strings = vec!["1", "2", "abc", "3", "4", "def"];
    
    // 解析数字,忽略非数字
    // filter_map() 接收一个返回 Option<T> 的闭包:
    // |s| s.parse().ok()
    // - s: &str 类型,字符串切片的引用
    // - s.parse(): 尝试解析为 i32,返回 Result<i32, ParseIntError>
    // - .ok(): 将 Result 转换为 Option,成功返回 Some(value),失败返回 None
    // - filter_map 会自动过滤掉 None,只保留 Some 中的值
    let numbers: Vec<i32> = strings.iter()
        .filter_map(|s| s.parse().ok())
        .collect();
    
    assert_eq!(numbers, vec![1, 2, 3, 4]);
    
    // 处理 Option:过滤掉 None
    // filter_map(|x| x) 中的 x 是 Option<i32>
    // 直接返回 x 会过滤掉 None,只保留 Some 中的值
    let maybe_numbers = vec![Some(1), None, Some(2), Some(3), None];
    let numbers: Vec<i32> = maybe_numbers.into_iter()
        .filter_map(|x| x)
        .collect();
    
    assert_eq!(numbers, vec![1, 2, 3]);
}

4. fold() - 累积计算

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 求和
    // fold() 接收两个参数:
    // 1. 初始值: 0
    // 2. 闭包: |acc, &x| acc + x
    //    - acc: 累积值,类型为 i32
    //    - &x: 当前元素的引用,解构为 i32
    //    - 返回值: 新的累积值
    let sum = numbers.iter()
        .fold(0, |acc, &x| acc + x);
    
    assert_eq!(sum, 15);
    
    // 连接字符串
    // fold() 参数:
    // 1. 初始值: String::new() (空字符串)
    // 2. 闭包: |mut acc, word| { acc.push_str(word); acc }
    //    - acc: 累积值,类型为 String (可变)
    //    - word: &str 类型,字符串切片的引用
    //    - 返回值: 更新后的累积值
    let words = vec!["Hello", " ", "World", "!"];
    let sentence = words.iter()
        .fold(String::new(), |mut acc, word| {
            acc.push_str(word);
            acc
        });
    
    assert_eq!(sentence, "Hello World!");
    
    // 计算阶乘
    // fold() 参数:
    // 1. 初始值: 1
    // 2. 闭包: |acc, x| acc * x
    //    - acc: 累积值,类型为 i32
    //    - x: 当前元素,类型为 i32
    let factorial = (1..=5).fold(1, |acc, x| acc * x);
    assert_eq!(factorial, 120);
}

5. reduce() - 归约操作

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 求和
    // reduce() 接收一个闭包作为参数:
    // |acc, &x| acc + x
    // - acc: 累积值,类型为 &i32 (第一个元素作为初始值)
    // - &x: 当前元素的引用,解构为 i32
    // - 返回值: 新的累积值 &i32
    // 注意:reduce() 第一个元素作为初始值,不需要单独提供
    let sum = numbers.iter()
        .reduce(|acc, &x| acc + x)
        .unwrap(); // 空集合会返回 None,所以用 unwrap()
    
    assert_eq!(sum, 15);
    
    // 找最大值
    // reduce() 参数:
    // |acc, &x| if x > *acc { &x } else { acc }
    // - acc: &i32,当前找到的最大值
    // - &x: &i32,当前元素
    // - 返回值: &i32,较大的那个元素的引用
    // - *acc: 解引用,获取 i32 值进行比较
    let max = numbers.iter()
        .reduce(|acc, &x| if x > *acc { &x } else { acc })
        .unwrap();
    
    assert_eq!(*max, 5);
    
    // 空集合返回 None
    let empty: Vec<i32> = vec![];
    let result = empty.iter().reduce(|acc, x| acc + x);
    assert_eq!(result, None);
}

6. take() - 取前 n 个元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 取前 3 个
    let first_three: Vec<i32> = numbers.iter()
        .take(3)
        .copied()
        .collect();
    
    assert_eq!(first_three, vec![1, 2, 3]);
    
    // 无限序列取前 5 个
    let infinite = (0..).take(5);
    let result: Vec<i32> = infinite.collect();
    
    assert_eq!(result, vec![0, 1, 2, 3, 4]);
}

7. skip() - 跳过前 n 个元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 跳过前 3 个,取后面的
    let rest: Vec<i32> = numbers.iter()
        .skip(3)
        .copied()
        .collect();
    
    assert_eq!(rest, vec![4, 5, 6, 7, 8, 9, 10]);
    
    // 跳过满足条件的元素
    let skip_even: Vec<i32> = numbers.iter()
        .skip_while(|&x| x % 2 == 1) // 跳过奇数
        .copied()
        .collect();
    
    assert_eq!(skip_even, vec![2, 3, 4, 5, 6, 7, 8, 9, 10]);
}

8. take_while() - 取满足条件的元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 1, 2, 3];
    
    // 取连续小于 4 的元素
    // take_while() 接收一个返回 bool 的闭包:
    // |&x| x < &4
    // - &x: 对元素的引用解构,x 是 i32 类型
    // - 返回值: bool,true 表示继续取,false 表示停止
    // - 注意:一旦遇到不满足条件的元素,后续所有元素都会被丢弃
    let result: Vec<i32> = numbers.iter()
        .take_while(|&x| x < &4)
        .copied()
        .collect();
    
    assert_eq!(result, vec![1, 2, 3]);
    
    // 字符串示例
    // take_while() 参数:
    // |word| word.starts_with('a')
    // - word: &str 类型,字符串切片的引用
    // - 返回值: bool,判断是否以 'a' 开头
    let words = vec!["apple", "banana", "cherry", "date"];
    let a_words: Vec<&str> = words.iter()
        .take_while(|word| word.starts_with('a'))
        .copied()
        .collect();
    
    assert_eq!(a_words, vec!["apple"]);
}

9. chain() - 连接多个迭代器

fn main() {
    let vec1 = vec![1, 2, 3];
    let vec2 = vec![4, 5, 6];
    
    // 连接两个向量
    let combined: Vec<i32> = vec1.iter()
        .chain(vec2.iter())
        .copied()
        .collect();
    
    assert_eq!(combined, vec![1, 2, 3, 4, 5, 6]);
    
    // 连接多个
    let vec3 = vec![7, 8];
    let all: Vec<i32> = vec1.iter()
        .chain(vec2.iter())
        .chain(vec3.iter())
        .copied()
        .collect();
    
    assert_eq!(all, vec![1, 2, 3, 4, 5, 6, 7, 8]);
}

10. zip() - 组合迭代器

fn main() {
    let names = vec!["Alice", "Bob", "Charlie"];
    let ages = vec![25, 30, 35];
    
    // 组合两个迭代器
    // zip() 接收另一个迭代器作为参数:
    // .zip(ages.iter())
    // - ages.iter(): 生成第二个迭代器
    // - 返回值: 迭代器,每个元素是 (&str, &i32) 元组
    // - map() 参数: |(&name, &age)| (name, age)
    //   - (&name, &age): 解构元组引用,name 是 &str,age 是 &i32
    //   - 返回值: (&str, i32) 元组 (age 被解引用)
    let people: Vec<(&str, i32)> = names.iter()
        .zip(ages.iter())
        .map(|(&name, &age)| (name, age))
        .collect();
    
    assert_eq!(people, vec![
        ("Alice", 25),
        ("Bob", 30),
        ("Charlie", 35)
    ]);
    
    // 处理不同长度:zip 以较短的为准
    let short = vec![1, 2];
    let long = vec![10, 20, 30, 40];
    let zipped: Vec<(i32, i32)> = short.iter()
        .zip(long.iter())
        .map(|(&a, &b)| (a, b))
        .collect();
    
    assert_eq!(zipped, vec![(1, 10), (2, 20)]);
}

11. enumerate() - 添加索引

fn main() {
    let fruits = vec!["apple", "banana", "cherry"];
    
    // 获取索引和值
    for (index, fruit) in fruits.iter().enumerate() {
        println!("{}: {}", index, fruit);
    }
    
    // 输出:
    // 0: apple
    // 1: banana
    // 2: cherry
    
    // 转换为带索引的元组
    let indexed: Vec<(usize, &str)> = fruits.iter()
        .enumerate()
        .map(|(i, &f)| (i, f))
        .collect();
    
    assert_eq!(indexed, vec![(0, "apple"), (1, "banana"), (2, "cherry")]);
}

12. rev() - 反转迭代器

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 反向迭代
    let reversed: Vec<i32> = numbers.iter()
        .rev()
        .copied()
        .collect();
    
    assert_eq!(reversed, vec![5, 4, 3, 2, 1]);
    
    // 反向枚举
    for (index, value) in numbers.iter().rev().enumerate() {
        println!("{}: {}", index, value);
    }
    
    // 输出:
    // 0: 5
    // 1: 4
    // 2: 3
    // 3: 2
    // 4: 1
}

13. flat_map() - 扁平化映射

fn main() {
    let nested = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
    
    // 扁平化嵌套向量
    // flat_map() 接收一个返回迭代器的闭包:
    // |vec| vec.iter()
    // - vec: &Vec<i32> 类型,对内层向量的引用
    // - 返回值: 迭代器 (vec.iter() 返回 Iter<'_, i32>)
    // - flat_map 会将多个迭代器合并为一个
    let flat: Vec<i32> = nested.iter()
        .flat_map(|vec| vec.iter())
        .copied()
        .collect();
    
    assert_eq!(flat, vec![1, 2, 3, 4, 5, 6]);
    
    // 字符串分割示例
    // flat_map() 参数:
    // |s| s.split_whitespace()
    // - s: &str 类型,字符串切片的引用
    // - s.split_whitespace(): 返回 SplitWhitespace 迭代器
    // - flat_map 将每个字符串分割的结果合并
    let sentences = vec!["hello world", "rust programming"];
    let words: Vec<&str> = sentences.iter()
        .flat_map(|s| s.split_whitespace())
        .collect();
    
    assert_eq!(words, vec!["hello", "world", "rust", "programming"]);
}

14. cloned() - 克隆元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 克隆引用
    let cloned: Vec<i32> = numbers.iter()
        .cloned()
        .collect();
    
    assert_eq!(cloned, vec![1, 2, 3, 4, 5]);
    
    // 对于实现了 Copy 的类型,cloned() 等同于 copied()
    let copied: Vec<i32> = numbers.iter()
        .copied()
        .collect();
    
    assert_eq!(copied, vec![1, 2, 3, 4, 5]);
}

15. collect() - 收集为集合

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 收集为 Vec
    // collect() 不接收参数,需要显式指定目标类型
    // - FromIterator trait 决定了支持哪些集合类型
    // - 需要配合 copied() 或 cloned() 处理引用
    let vec: Vec<i32> = numbers.iter()
        .filter(|&x| x % 2 == 0)
        .copied()
        .collect();
    
    // 收集为 String
    // String 实现了 FromIterator<char>
    // - map() 将每个数字转换为 String
    // - collect() 将所有 String 拼接
    let string: String = numbers.iter()
        .map(|x| x.to_string())
        .collect();
    
    // 收集为 HashMap
    // HashMap 实现了 FromIterator<(K, V)>
    // - map() 生成 (key, value) 元组
    // - collect() 自动构建 HashMap
    use std::collections::HashMap;
    let map: HashMap<i32, String> = numbers.iter()
        .map(|&x| (x, format!("num_{}", x)))
        .collect();
    
    // 收集为 HashSet
    // HashSet 自动去重
    use std::collections::HashSet;
    let set: HashSet<i32> = vec![1, 2, 2, 3, 3, 4].iter()
        .copied()
        .collect();
    
    assert_eq!(set.len(), 4); // 自动去重
}

16. sum()product() - 求和与求积

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 求和
    // sum() 不接收参数,返回 T 类型
    // - 需要显式指定返回类型
    // - 自动处理累加逻辑
    let sum: i32 = numbers.iter().sum();
    assert_eq!(sum, 15);
    
    // 求积
    // product() 不接收参数,返回 T 类型
    // - 需要显式指定返回类型
    // - 计算所有元素的乘积
    let product: i32 = numbers.iter().product();
    assert_eq!(product, 120);
    
    // 浮点数
    // sum() 和 product() 支持各种数值类型
    let floats = vec![1.5, 2.0, 3.5];
    let float_sum: f64 = floats.iter().sum();
    assert_eq!(float_sum, 7.0);
}

17. max()min() - 最大最小值

fn main() {
    let numbers = vec![3, 1, 4, 1, 5, 9, 2, 6];
    
    // 最大值
    // max() 不接收参数,返回 Option<&T>
    // - 对于有序类型,比较大小
    // - 空迭代器返回 None
    let max = numbers.iter().max().unwrap();
    assert_eq!(*max, 9);
    
    // 最小值
    // min() 不接收参数,返回 Option<&T>
    let min = numbers.iter().min().unwrap();
    assert_eq!(*min, 1);
    
    // 自定义比较
    // max_by_key() 接收一个闭包作为参数:
    // |word| word.len()
    // - word: &str 类型,字符串切片的引用
    // - 返回值: usize,用于比较的键值
    // - 函数会返回键值最大的元素
    let words = vec!["apple", "banana", "cherry"];
    let longest = words.iter().max_by_key(|word| word.len()).unwrap();
    assert_eq!(*longest, "banana");
}

18. any()all() - 检查条件

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 是否存在大于 3 的数
    // any() 接收一个返回 bool 的闭包:
    // |&x| x > 3
    // - &x: 对元素的引用解构,x 是 i32 类型
    // - 返回值: bool,true 表示存在满足条件的元素
    // - 短路求值:找到第一个满足条件的就返回
    let has_large = numbers.iter().any(|&x| x > 3);
    assert_eq!(has_large, true);
    
    // 是否所有数都小于 10
    // all() 接收一个返回 bool 的闭包:
    // |&x| x < 10
    // - 返回值: bool,true 表示所有元素都满足条件
    // - 短路求值:找到第一个不满足的就返回 false
    let all_small = numbers.iter().all(|&x| x < 10);
    assert_eq!(all_small, true);
    
    // 是否存在负数
    let has_negative = numbers.iter().any(|&x| x < 0);
    assert_eq!(has_negative, false);
}

19. find() - 查找元素

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 查找第一个大于 3 的数
    // find() 接收一个返回 bool 的闭包:
    // |&&x| x > 3
    // - &&x: 对引用的引用解构,x 是 i32 类型
    //   (第一个 & 来自 iter(),第二个 & 来自 find 的参数)
    // - 返回值: bool,true 表示找到目标
    // - 返回值: Option<&T>,找到返回 Some,否则 None
    let found = numbers.iter().find(|&&x| x > 3);
    assert_eq!(found, Some(&4));
    
    // 查找不存在的元素
    let not_found = numbers.iter().find(|&&x| x > 10);
    assert_eq!(not_found, None);
    
    // 查找字符串
    // find() 参数:
    // |&&word| word == "awesome"
    // - &&word: &str 类型
    let words = vec!["rust", "is", "awesome"];
    let awesome = words.iter().find(|&&word| word == "awesome");
    assert_eq!(awesome, Some(&"awesome"));
}

20. position() - 查找位置

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 查找第一个大于 3 的位置
    // position() 接收一个返回 bool 的闭包:
    // |&x| x > 3
    // - &x: 对元素的引用解构,x 是 i32 类型
    // - 返回值: bool,true 表示找到目标
    // - 返回值: Option<usize>,元素的索引位置
    let pos = numbers.iter().position(|&x| x > 3);
    assert_eq!(pos, Some(3));
    
    // 查找不存在元素的位置
    let not_pos = numbers.iter().position(|&x| x > 10);
    assert_eq!(not_pos, None);
    
    // 查找重复元素
    // position() 返回第一个匹配的索引
    let with_duplicates = vec![1, 2, 3, 2, 4];
    let first_duplicate = with_duplicates.iter()
        .position(|&x| x == 2);
    assert_eq!(first_duplicate, Some(1));
}

21. fold_while() - 条件累积

use std::iter::FoldWhile::{Continue, Done};

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 累加直到超过 20
    // fold_while() 接收两个参数:
    // 1. 初始值: 0
    // 2. 闭包: |acc, &x| { ... }
    //    - acc: 累积值,类型为 i32
    //    - &x: 当前元素的引用,解构为 i32
    //    - 返回值: FoldWhile<i32>
    //      - Continue(sum): 继续迭代
    //      - Done(sum): 停止迭代
    // - into_inner(): 从 FoldWhile 中提取最终值
    let result = numbers.iter()
        .fold_while(0, |acc, &x| {
            let sum = acc + x;
            if sum > 20 {
                Done(sum)
            } else {
                Continue(sum)
            }
        });
    
    assert_eq!(result.into_inner(), 21);
}

22. scan() - 带状态的转换

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 计算前缀和
    // scan() 接收两个参数:
    // 1. 初始状态: 0
    // 2. 闭包: |state, &x| { ... }
    //    - state: &mut i32,可变状态引用
    //    - &x: 当前元素的引用,解构为 i32
    //    - 返回值: Option<i32>,Some 表示输出值,None 表示停止
    let prefix_sum: Vec<i32> = numbers.iter()
        .scan(0, |state, &x| {
            *state += x;
            Some(*state)
        })
        .collect();
    
    assert_eq!(prefix_sum, vec![1, 3, 6, 10, 15]);
    
    // 斐波那契数列
    // scan() 参数:
    // 1. 初始状态: (0, 1) 元组
    // 2. 闭包: |state, _| { ... }
    //    - state: &mut (i32, i32),可变状态引用
    //    - _: (),忽略输入值
    //    - 返回值: Option<i32>,斐波那契数
    let fib: Vec<i32> = (0..)
        .scan((0, 1), |state, _| {
            let next = state.0 + state.1;
            *state = (state.1, next);
            Some(next)
        })
        .take(10)
        .collect();
    
    assert_eq!(fib, vec![1, 2, 3, 5, 8, 13, 21, 34, 55, 89]);
}

23. cycle() - 循环迭代器

fn main() {
    let numbers = vec![1, 2, 3];
    
    // 重复 3 次
    // cycle() 不接收参数,返回一个无限循环的迭代器
    // - 会不断重复原迭代器的元素
    // - 通常与 take() 配合使用来限制重复次数
    let repeated: Vec<i32> = numbers.iter()
        .cycle()
        .take(9)
        .copied()
        .collect();
    
    assert_eq!(repeated, vec![1, 2, 3, 1, 2, 3, 1, 2, 3]);
    
    // 无限循环
    // cycle() 生成无限序列,需要手动控制或使用 take()
    let mut iter = [1, 2].iter().cycle();
    assert_eq!(iter.next(), Some(&1));
    assert_eq!(iter.next(), Some(&2));
    assert_eq!(iter.next(), Some(&1));
    assert_eq!(iter.next(), Some(&2));
}

24. chunks()windows() - 窗口操作

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6];
    
    // 分块,每块 2 个元素
    // chunks() 接收一个 usize 参数:
    // - 2: 每块的大小
    // - 返回值: 迭代器,每个元素是 &[i32] (切片引用)
    // - 注意:最后一块可能小于指定大小
    let chunks: Vec<&[i32]> = numbers.chunks(2).collect();
    assert_eq!(chunks, vec![&[1, 2], &[3, 4], &[5, 6]]);
    
    // 滑动窗口,窗口大小 3
    // windows() 接收一个 usize 参数:
    // - 3: 窗口大小
    // - 返回值: 迭代器,每个元素是 &[i32] (窗口切片)
    // - 注意:窗口会滑动,每个元素可能出现在多个窗口中
    let windows: Vec<&[i32]> = numbers.windows(3).collect();
    assert_eq!(windows, vec![&[1, 2, 3], &[2, 3, 4], &[3, 4, 5], &[4, 5, 6]]);
    
    // 计算移动平均
    // windows(3) 生成窗口切片
    // map() 参数:
    // |window| window.iter().sum::<i32>() as f64 / 3.0
    // - window: &[i32],窗口切片
    // - window.iter().sum::<i32>(): 计算窗口内元素和
    // - 除以 3.0 得到平均值
    let moving_avg: Vec<f64> = numbers.windows(3)
        .map(|window| window.iter().sum::<i32>() as f64 / 3.0)
        .collect();
    
    assert_eq!(moving_avg, vec![2.0, 3.0, 4.0, 5.0]);
}

25. step_by() - 步长迭代

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 每隔 2 个取一个
    // step_by() 接收一个 usize 参数:
    // - 2: 步长,表示每隔几个元素取一个
    // - 返回值: 迭代器,从第一个元素开始,按步长取元素
    let every_other: Vec<i32> = numbers.iter()
        .step_by(2)
        .copied()
        .collect();
    
    assert_eq!(every_other, vec![1, 3, 5, 7, 9]);
    
    // 从索引 1 开始,每隔 3 个
    // step_by() 参数:
    // - 3: 步长
    // - 注意:step_by 作用于 skip 之后的结果
    let skipped: Vec<i32> = numbers.iter()
        .skip(1)
        .step_by(3)
        .copied()
        .collect();
    
    assert_eq!(skipped, vec![2, 5, 8]);
}

高级迭代器技巧

1. 自定义迭代器

struct Countdown {
    count: u32,
}

impl Iterator for Countdown {
    type Item = u32;
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.count == 0 {
            None
        } else {
            let current = self.count;
            self.count -= 1;
            Some(current)
        }
    }
}

fn main() {
    let countdown = Countdown { count: 3 };
    let result: Vec<u32> = countdown.collect();
    assert_eq!(result, vec![3, 2, 1]);
}

2. 迭代器链

fn main() {
    let result: Vec<i32> = (1..=10)
        .filter(|x| x % 2 == 0)      // [2, 4, 6, 8, 10]
        .map(|x| x * x)              // [4, 16, 36, 64, 100]
        .filter(|x| x > &20)         // [36, 64, 100]
        .rev()                       // [100, 64, 36]
        .take(2)                     // [100, 64]
        .collect();
    
    assert_eq!(result, vec![100, 64]);
}

3. 性能优化:使用迭代器而非循环

fn main() {
    let numbers = vec![1, 2, 3, 4, 5];
    
    // 迭代器方式(推荐)
    let sum_iter: i32 = numbers.iter().sum();
    
    // 传统循环方式
    let mut sum_loop = 0;
    for &num in &numbers {
        sum_loop += num;
    }
    
    assert_eq!(sum_iter, sum_loop);
    
    // 迭代器通常更高效,因为编译器可以更好地优化
    // 并且避免了边界检查
}

总结

Rust 的迭代器系统是其最强大的特性之一:

  1. 零成本抽象:迭代器在编译时被优化为高效的代码
  2. 类型安全:编译器确保所有操作都是类型安全的
  3. 惰性求值:大多数操作是惰性的,只在需要时执行
  4. 组合性:可以轻松组合多个操作
  5. 可读性:函数式风格使代码更清晰

掌握迭代器可以让你写出更简洁、更高效、更安全的 Rust 代码。通过组合各种迭代器方法,你可以避免手动编写循环,减少错误,并让代码更具表达力。