迭代器与闭包
闭包和迭代器是 Rust 函数式编程的核心。它们让你能够编写简洁、表达力强的代码。
闭包(Closures)
Section titled “闭包(Closures)”闭包是可以捕获环境的匿名函数。
fn main() { // 普通函数 fn add_one_fn(x: i32) -> i32 { x + 1 }
// 闭包的几种写法 let add_one_v1 = |x: i32| -> i32 { x + 1 }; let add_one_v2 = |x: i32| { x + 1 }; let add_one_v3 = |x: i32| x + 1; let add_one_v4 = |x| x + 1; // 类型可以推断
println!("{}", add_one_v1(5));}闭包可以捕获定义它的作用域中的变量:
fn main() { let x = 4;
let equal_to_x = |z| z == x; // 捕获了 x
let y = 4; assert!(equal_to_x(y));}闭包的三种捕获方式
Section titled “闭包的三种捕获方式”闭包根据使用方式自动选择捕获方式:
1. 借用(Fn)
Section titled “1. 借用(Fn)”fn main() { let list = vec![1, 2, 3]; let only_borrows = || println!("{:?}", list);
println!("调用前: {:?}", list); only_borrows(); println!("调用后: {:?}", list); // list 仍然可用}2. 可变借用(FnMut)
Section titled “2. 可变借用(FnMut)”fn main() { let mut list = vec![1, 2, 3]; let mut borrows_mutably = || list.push(7);
// println!("{:?}", list); // 错误!已经有可变借用 borrows_mutably(); println!("{:?}", list); // [1, 2, 3, 7]}3. 获取所有权(FnOnce)
Section titled “3. 获取所有权(FnOnce)”fn main() { let list = vec![1, 2, 3];
// move 强制获取所有权 let takes_ownership = move || println!("{:?}", list);
// println!("{:?}", list); // 错误!list 已被移动 takes_ownership();}闭包作为参数
Section titled “闭包作为参数”fn apply<F>(f: F, x: i32) -> i32where F: Fn(i32) -> i32,{ f(x)}
fn main() { let double = |x| x * 2; let result = apply(double, 5); println!("{}", result); // 10}三种闭包 Trait
Section titled “三种闭包 Trait”| Trait | 含义 | 调用方式 |
|---|---|---|
FnOnce | 只能调用一次,获取所有权 | self |
FnMut | 可以多次调用,可变借用 | &mut self |
Fn | 可以多次调用,不可变借用 | &self |
关系:Fn : FnMut : FnOnce(每个都是前一个的子 trait)
fn call_once<F: FnOnce()>(f: F) { f(); // f(); // 错误!FnOnce 只能调用一次}
fn call_many<F: Fn()>(f: F) { f(); f(); f(); // OK,可以调用多次}fn make_adder(n: i32) -> impl Fn(i32) -> i32 { move |x| x + n}
fn main() { let add_5 = make_adder(5); println!("{}", add_5(10)); // 15}迭代器(Iterators)
Section titled “迭代器(Iterators)”迭代器是一种模式,允许依次处理序列中的元素。
fn main() { let v = vec![1, 2, 3];
// 不可变引用迭代器 let iter = v.iter();
// 可变引用迭代器 let mut v = vec![1, 2, 3]; let iter_mut = v.iter_mut();
// 获取所有权的迭代器 let v = vec![1, 2, 3]; let into_iter = v.into_iter();}Iterator trait
Section titled “Iterator trait”pub trait Iterator { type Item; fn next(&mut self) -> Option<Self::Item>; // 还有很多默认方法...}fn main() { let v = vec![1, 2, 3]; let mut iter = v.iter();
assert_eq!(iter.next(), Some(&1)); assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next(), Some(&3)); assert_eq!(iter.next(), None);}for 循环与迭代器
Section titled “for 循环与迭代器”fn main() { let v = vec![1, 2, 3];
for val in v.iter() { println!("{}", val); }
// 等价于 let v = vec![1, 2, 3]; for val in &v { println!("{}", val); }}迭代器适配器
Section titled “迭代器适配器”适配器(adapter)消费一个迭代器,产生另一个迭代器。
转换每个元素:
fn main() { let v = vec![1, 2, 3]; let v2: Vec<_> = v.iter().map(|x| x * 2).collect(); println!("{:?}", v2); // [2, 4, 6]}filter
Section titled “filter”过滤元素:
fn main() { let v = vec![1, 2, 3, 4, 5, 6]; let even: Vec<_> = v.iter().filter(|x| *x % 2 == 0).collect(); println!("{:?}", even); // [2, 4, 6]}take 和 skip
Section titled “take 和 skip”fn main() { let v = vec![1, 2, 3, 4, 5];
let first_three: Vec<_> = v.iter().take(3).collect(); println!("{:?}", first_three); // [1, 2, 3]
let skip_two: Vec<_> = v.iter().skip(2).collect(); println!("{:?}", skip_two); // [3, 4, 5]}enumerate
Section titled “enumerate”带索引遍历:
fn main() { let v = vec!['a', 'b', 'c'];
for (index, value) in v.iter().enumerate() { println!("{}: {}", index, value); }}合并两个迭代器:
fn main() { let a = [1, 2, 3]; let b = [4, 5, 6];
let zipped: Vec<_> = a.iter().zip(b.iter()).collect(); println!("{:?}", zipped); // [(1, 4), (2, 5), (3, 6)]}flatten
Section titled “flatten”展平嵌套结构:
fn main() { let nested = vec![vec![1, 2], vec![3, 4], vec![5]]; let flat: Vec<_> = nested.into_iter().flatten().collect(); println!("{:?}", flat); // [1, 2, 3, 4, 5]}连接两个迭代器:
fn main() { let a = [1, 2, 3]; let b = [4, 5, 6];
let chained: Vec<_> = a.iter().chain(b.iter()).collect(); println!("{:?}", chained); // [1, 2, 3, 4, 5, 6]}消费器(consumer)消费迭代器,产生最终结果。
collect
Section titled “collect”收集为集合:
use std::collections::HashMap;
fn main() { // 收集为 Vec let v: Vec<_> = (1..=5).collect();
// 收集为 HashMap let map: HashMap<_, _> = vec![("a", 1), ("b", 2)].into_iter().collect();}sum 和 product
Section titled “sum 和 product”fn main() { let sum: i32 = (1..=5).sum(); println!("sum: {}", sum); // 15
let product: i32 = (1..=5).product(); println!("product: {}", product); // 120}自定义累积操作:
fn main() { let v = vec![1, 2, 3, 4, 5];
// 初始值 0,累积函数 let sum = v.iter().fold(0, |acc, x| acc + x); println!("sum: {}", sum); // 15
// 字符串拼接 let words = vec!["hello", "world"]; let sentence = words.iter().fold(String::new(), |acc, word| { if acc.is_empty() { word.to_string() } else { format!("{} {}", acc, word) } }); println!("{}", sentence); // "hello world"}find 和 position
Section titled “find 和 position”fn main() { let v = vec![1, 2, 3, 4, 5];
// 找到第一个满足条件的元素 let found = v.iter().find(|&&x| x > 3); println!("{:?}", found); // Some(4)
// 找到位置 let pos = v.iter().position(|&x| x > 3); println!("{:?}", pos); // Some(3)}any 和 all
Section titled “any 和 all”fn main() { let v = vec![1, 2, 3, 4, 5];
let has_even = v.iter().any(|&x| x % 2 == 0); println!("有偶数: {}", has_even); // true
let all_positive = v.iter().all(|&x| x > 0); println!("全是正数: {}", all_positive); // true}count、min、max
Section titled “count、min、max”fn main() { let v = vec![3, 1, 4, 1, 5, 9, 2, 6];
println!("数量: {}", v.iter().count()); // 8 println!("最小: {:?}", v.iter().min()); // Some(1) println!("最大: {:?}", v.iter().max()); // Some(9)}迭代器方法可以链式调用:
fn main() { let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let result: Vec<_> = v .iter() .filter(|&&x| x % 2 == 0) // 过滤偶数 .map(|&x| x * x) // 平方 .take(3) // 取前 3 个 .collect();
println!("{:?}", result); // [4, 16, 36]}实现自定义迭代器
Section titled “实现自定义迭代器”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 { self.count += 1; Some(self.count) } else { None } }}
fn main() { let counter = Counter::new(5);
for num in counter { println!("{}", num); } // 输出: 1, 2, 3, 4, 5}迭代器是零成本抽象,编译后与手写循环性能相同:
// 这两段代码编译后性能一样let sum: i32 = (1..=100).sum();
let mut sum = 0;for i in 1..=100 { sum += i;}练习 1:使用闭包
Section titled “练习 1:使用闭包”编写一个函数,接收闭包并应用到每个元素:
fn apply_to_all<F>(v: Vec<i32>, f: F) -> Vec<i32>where F: Fn(i32) -> i32,{ // 你的代码}
fn main() { let v = vec![1, 2, 3, 4, 5]; let doubled = apply_to_all(v, |x| x * 2); println!("{:?}", doubled); // [2, 4, 6, 8, 10]}练习 2:迭代器链
Section titled “练习 2:迭代器链”使用迭代器:过滤偶数 → 平方 → 求和
fn main() { let v = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let result: i32 = // 你的代码
println!("结果: {}", result); // 应该是 4+16+36+64+100 = 220}练习 3:实现迭代器
Section titled “练习 3:实现迭代器”实现一个 Fibonacci 迭代器:
struct Fibonacci { curr: u64, next: u64,}
impl Fibonacci { fn new() -> Self { Fibonacci { curr: 0, next: 1 } }}
impl Iterator for Fibonacci { type Item = u64;
fn next(&mut self) -> Option<Self::Item> { // 你的代码 }}
fn main() { let fib: Vec<_> = Fibonacci::new().take(10).collect(); println!("{:?}", fib); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]}练习 4:fold 实现
Section titled “练习 4:fold 实现”使用 fold 拼接字符串数组:
fn main() { let words = vec!["Hello", "World", "Rust"];
let sentence = // 使用 fold 拼接,用空格分隔
println!("{}", sentence); // "Hello World Rust"}掌握了迭代器和闭包后,下一章我们将学习智能指针——Rust 中管理堆内存的重要工具。