12. 闭包 (Closures) 🟢
Rust 的 闭包 是可以保存在变量中或作为参数传递给其他函数的 匿名函数。你可以在一个地方创建闭包,然后在不同的上下文中调用闭包进行求值。
1. 基础语法
闭包使用竖线 || 而不是圆括号 () 来放置参数。
fn main() {
let add_one = |x: i32| x + 1;
let result = add_one(5);
println!("结果是 {result}");
}
2. 捕获环境
与函数不同,闭包可以从定义它们的作用域中捕获值。
fn main() {
let x = 4;
let equal_to_x = |z| z == x; // 捕获了 `x`
let y = 4;
assert!(equal_to_x(y));
}
3. 闭包 Trait:Fn、FnMut 与 FnOnce
闭包以三种方式从其环境中捕获值,这三种方式对应于函数获取参数的三种方式:
FnOnce:消耗其从闭包外层作用域捕获的变量(只能被调用一次)。FnMut:以可变方式从其环境中借用值(可以修改环境)。Fn:以不可变方式从其环境中借用值。
4. 使用 move 移动所有权
如果你想强制闭包获取其在环境中使用的值的所有权,可以在参数列表之前使用 move 关键字。
use std::thread;
fn main() {
let x = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("这是一个向量:{:?}", x);
});
handle.join().unwrap();
}
对 C/C++ 开发者的总结
- In C++:你使用 Lambdas (
[=](int x) { ... })。你必须手动指定如何捕获变量(按值[=]、按引用[&]等)。 - In Rust:闭包会根据环境变量的使用方式自动推断应使用哪种捕获 Trait。
move关键字用于将所有权移动到闭包中,类似于 C++ 中的[x = std::move(x)]。