闭包应用
> 掌握闭包作为函数参数的用法,学会与迭代器配合处理数据。
闭包作为函数参数
基本用法
rust
▶ Run// 接受闭包作为参数
fn apply<F>(f: F)
where
F: FnOnce(i32) -> i32,
{
let result = f(42);
println!("结果:{}", result);
}
fn main() {
// 传递闭包
apply(|x| x + 1);
apply(|x| x * 2);
// 也可以传递函数
fn add_one(x: i32) -> i32 { x + 1 }
apply(add_one);
}实际应用:数据处理
rust
▶ Run// 通用的数据处理函数
fn process_data<F>(data: Vec<i32>, transform: F) -> Vec<i32>
where
F: Fn(i32) -> i32,
{
data.into_iter().map(transform).collect()
}
fn main() {
let data = vec![1, 2, 3, 4, 5];
// 不同的转换逻辑
let doubled = process_data(data.clone(), |x| x * 2);
let squared = process_data(data.clone(), |x| x * x);
let offset = process_data(data.clone(), |x| x + 10);
println!("原始:{:?}", data);
println!("翻倍:{:?}", doubled);
println!("平方:{:?}", squared);
println!("偏移:{:?}", offset);
}回调模式
rust
▶ Run// 带有回调的异步操作模拟
fn fetch_with_callback<F>(url: &str, callback: F)
where
F: FnOnce(Result<String, String>),
{
// 模拟网络请求
let result = if url.is_empty() {
Err("URL 不能为空".to_string())
} else {
Ok(format!("从 {} 获取的数据", url))
};
// 调用回调
callback(result);
}
fn main() {
fetch_with_callback("https://example.com", |result| {
match result {
Ok(data) => println!("成功:{}", data),
Err(e) => println!("错误:{}", e),
}
});
fetch_with_callback("", |result| {
if let Err(e) = result {
println!("处理错误:{}", e);
}
});
}迭代器与闭包
常用迭代器方法
rust
▶ Runfn main() {
let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// map - 转换每个元素
let doubled: Vec<i32> = numbers
.iter()
.map(|x| x * 2)
.collect();
println!("翻倍:{:?}", doubled);
// filter - 过滤元素
let evens: Vec<&i32> = numbers
.iter()
.filter(|x| *x % 2 == 0)
.collect();
println!("偶数:{:?}", evens);
// filter_map - 过滤并转换
let squared_evens: Vec<i32> = numbers
.iter()
.filter_map(|x| {
if *x % 2 == 0 {
Some(x * x)
} else {
None
}
})
.collect();
println!("偶数的平方:{:?}", squared_evens);
}累积操作
rust
▶ Runfn main() {
let numbers = vec![1, 2, 3, 4, 5];
// fold - 累积求和
let sum: i32 = numbers
.iter()
.fold(0, |acc, x| acc + x);
println!("总和:{}", sum); // 15
// fold - 累积乘积
let product: i32 = numbers
.iter()
.fold(1, |acc, x| acc * x);
println!("乘积:{}", product); // 120
// scan - 带状态的迭代
let mut accumulated = 0;
let running_sum: Vec<i32> = numbers
.iter()
.scan(0, |state, &x| {
*state += x;
Some(*state)
})
.collect();
println!("累加和:{:?}", running_sum); // [1, 3, 6, 10, 15]
}查找与检查
rust
▶ Runfn main() {
let numbers = vec![1, 2, 3, 4, 5];
// find - 查找第一个匹配的元素
let found = numbers.iter().find(|x| *x > 3);
println!("找到:{:?}", found); // Some(4)
// position - 查找索引
let pos = numbers.iter().position(|x| *x == 3);
println!("位置:{:?}", pos); // Some(2)
// rfind - 从右向左查找
let rfound = numbers.iter().rfind(|x| *x > 2);
println!("从右查找:{:?}", rfound); // Some(5)
// all - 检查是否全部满足
let all_positive = numbers.iter().all(|x| *x > 0);
println!("全部正数:{}", all_positive); // true
// any - 检查是否有任意满足
let has_even = numbers.iter().any(|x| *x % 2 == 0);
println!("有偶数:{}", has_even); // true
// count - 计数
let even_count = numbers.iter().filter(|x| *x % 2 == 0).count();
println!("偶数个数:{}", even_count); // 2
}排序与闭包
rust
▶ Runfn main() {
// 数字排序
let mut numbers = vec![5, 2, 8, 1, 9];
numbers.sort();
println!("升序:{:?}", numbers);
// 自定义排序:降序
let mut numbers = vec![5, 2, 8, 1, 9];
numbers.sort_by(|a, b| b.cmp(a));
println!("降序:{:?}", numbers);
// 按绝对值排序
let mut numbers = vec![-5, 2, -8, 1, 9];
numbers.sort_by_key(|x| x.abs());
println!("按绝对值:{:?}", numbers);
// 字符串按长度排序
let mut words = vec!["rust", "a", "programming", "is", "language"];
words.sort_by_key(|s| s.len());
println!("按长度:{:?}", words);
// 复杂排序:先按长度,再按字典序
let mut words = vec!["rust", "a", "programming", "is", "language"];
words.sort_by(|a, b| {
a.len().cmp(&b.len()).then(a.cmp(b))
});
println!("复杂排序:{:?}", words);
}
---
## 小结
- 闭包作为函数参数,实现回调模式和高阶函数
- 迭代器方法 map、filter、fold 都接受闭包
- 链式调用实现简洁的数据处理管道
- 排序方法 sort_by、sort_by_key 使用闭包定制比较
- find、position、all、any 是常用的查询方法
## 练习题
详见:[练习题](../../exercises/18-closures)