按值捕获
- 适用场景:当闭包需要拥有变量的所有权,并可能在之后的某个时间点移动或修改该变量时,适合按值捕获。例如,当闭包需要将捕获的变量传递给另一个函数,并且之后原变量不再使用的场景。
- 区别:按值捕获时,闭包获取变量的所有权,原变量在闭包外部不可再使用。
- 代码示例:
fn main() {
let x = 5;
let closure = move || {
println!("x inside closure: {}", x);
};
// 下面这行代码会报错,因为x的所有权已经被闭包获取
// println!("x outside closure: {}", x);
closure();
}
按可变引用捕获
- 适用场景:当闭包需要修改捕获的变量,并且该变量在闭包外部也可能需要被使用时,适合按可变引用捕获。例如,在对一个共享的可变数据结构进行增量更新操作的闭包中使用。
- 区别:按可变引用捕获允许闭包修改变量,同时要求在闭包使用期间,该变量在其他地方不能被借用(遵循 Rust 的借用规则)。
- 代码示例:
fn main() {
let mut x = 5;
let closure = || {
x += 1;
println!("x inside closure: {}", x);
};
closure();
println!("x outside closure: {}", x);
}
按不可变引用捕获
- 适用场景:当闭包只需要读取捕获的变量,并且该变量在闭包外部也可能需要被使用时,适合按不可变引用捕获。例如,在对一个共享的只读数据结构进行计算操作的闭包中使用。
- 区别:按不可变引用捕获只允许闭包读取变量,在闭包使用期间,该变量可以在其他地方被不可变借用,但不能被可变借用。
- 代码示例:
fn main() {
let x = 5;
let closure = || {
println!("x inside closure: {}", x);
};
closure();
println!("x outside closure: {}", x);
}