Appearance
Rust 闭包
闭包是 Rust 中一种可以捕获环境变量的匿名函数。本章节将介绍 Rust 中的闭包。
闭包定义
闭包的定义使用 || 语法:
rust
fn main() {
// 简单闭包
let add_one = |x| x + 1;
println!("add_one(5) = {}", add_one(5));
// 带类型注解的闭包
let add_two = |x: i32| -> i32 { x + 2 };
println!("add_two(5) = {}", add_two(5));
// 多参数闭包
let add = |x, y| x + y;
println!("add(5, 3) = {}", add(5, 3));
// 无参数闭包
let say_hello = || println!("Hello!");
say_hello();
}闭包捕获环境变量
闭包可以捕获其定义环境中的变量:
rust
fn main() {
let x = 5;
// 捕获 x 作为不可变引用
let add_x = |y| x + y;
println!("add_x(3) = {}", add_x(3));
// 捕获 x 作为可变引用
let mut y = 10;
let mut add_to_y = |z| y += z;
add_to_y(5);
println!("y = {}", y);
// 捕获 x 的所有权
let s = String::from("Hello");
let take_s = move || println!("s = {}", s);
take_s();
// println!("s = {}", s); // 错误:s 的所有权已经被转移
}闭包的类型推断
Rust 会为每个闭包创建一个唯一的类型,但闭包可以通过 Trait 来统一处理:
Fn:不可变捕获环境FnMut:可变捕获环境FnOnce:消费捕获的环境
rust
fn main() {
// Fn 闭包
let x = 5;
let add_x = |y| x + y;
// FnMut 闭包
let mut y = 10;
let mut add_to_y = |z| y += z;
// FnOnce 闭包
let s = String::from("Hello");
let take_s = move || println!("s = {}", s);
}闭包作为参数
可以将闭包作为函数参数:
rust
fn apply<F>(f: F) where F: FnOnce() {
f();
}
fn apply_to_3<F>(f: F) -> i32 where F: Fn(i32) -> i32 {
f(3)
}
fn main() {
let greeting = "Hello";
let say_hello = || println!("{}", greeting);
apply(say_hello);
let add_one = |x| x + 1;
println!("apply_to_3(add_one) = {}", apply_to_3(add_one));
// 直接传递闭包
println!("apply_to_3(|x| x * 2) = {}", apply_to_3(|x| x * 2));
}闭包作为返回值
可以返回闭包,但需要使用 Box 来包装:
rust
fn make_adder(x: i32) -> Box<dyn Fn(i32) -> i32> {
Box::new(move |y| x + y)
}
fn main() {
let add5 = make_adder(5);
println!("add5(3) = {}", add5(3));
let add10 = make_adder(10);
println!("add10(3) = {}", add10(3));
}闭包的应用
迭代器适配器
rust
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
// map 方法使用闭包
let doubled: Vec<_> = numbers.iter().map(|&x| x * 2).collect();
println!("Doubled: {:?}", doubled);
// filter 方法使用闭包
let even: Vec<_> = numbers.iter().filter(|&&x| x % 2 == 0).collect();
println!("Even: {:?}", even);
}延迟计算
rust
fn main() {
let expensive_calculation = || {
println!("Performing expensive calculation...");
// 模拟昂贵的计算
std::thread::sleep(std::time::Duration::from_secs(1));
42
};
println!("First call:");
println!("Result: {}", expensive_calculation());
println!("Second call:");
println!("Result: {}", expensive_calculation());
}回调函数
rust
fn perform_operation<F>(callback: F) where F: FnOnce(i32) {
let result = 42;
callback(result);
}
fn main() {
perform_operation(|result| {
println!("Operation result: {}", result);
});
}总结
- 闭包:可以捕获环境变量的匿名函数
- 语法:使用
||定义 - 捕获方式:不可变引用、可变引用、所有权
- Trait:
Fn、FnMut、FnOnce - 应用:迭代器适配器、延迟计算、回调函数
闭包是 Rust 中非常强大的特性,它允许我们编写更灵活、更简洁的代码。通过本章节的学习,你应该已经掌握了 Rust 中闭包的使用方法。