Rust 迭代器
什么是 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 的迭代器系统是其最强大的特性之一:
- 零成本抽象:迭代器在编译时被优化为高效的代码
- 类型安全:编译器确保所有操作都是类型安全的
- 惰性求值:大多数操作是惰性的,只在需要时执行
- 组合性:可以轻松组合多个操作
- 可读性:函数式风格使代码更清晰
掌握迭代器可以让你写出更简洁、更高效、更安全的 Rust 代码。通过组合各种迭代器方法,你可以避免手动编写循环,减少错误,并让代码更具表达力。

