面试题答案
一键面试Rust中闭包的定义
闭包是可以捕获其所在环境的匿名函数。它可以作为值进行传递,并且可以在定义它的作用域之外调用。
声明闭包
闭包使用 ||
语法声明,||
之前为参数列表,之后为函数体。例如:
let closure = |x| x + 1;
这里定义了一个接收一个参数 x
并返回 x + 1
的闭包,并将其赋值给变量 closure
。
闭包对环境变量的三种捕获方式及其适用场景
- 按值捕获
- 方式:闭包默认按值捕获环境中的变量。例如:
fn main() {
let num = 5;
let closure = || {
println!("The value of num is: {}", num);
};
closure();
}
- **适用场景**:当闭包需要拥有环境变量的所有权,并且不需要修改该变量时使用。例如在需要将闭包传递给其他函数,而该闭包仅用于读取环境变量的场景。
2. 按不可变引用捕获 - 方式:如果环境变量较大,按值捕获会导致性能问题,此时可以按不可变引用捕获。例如:
fn main() {
let big_string = String::from("a very big string");
let closure = || {
println!("The big string is: {}", big_string);
};
closure();
}
这里 big_string
实际上是按不可变引用被闭包捕获的,因为闭包内没有对其进行修改。如果需要明确表示,可以这样写:
fn main() {
let big_string = String::from("a very big string");
let closure: impl Fn() = || {
println!("The big string is: {}", big_string);
};
closure();
}
- **适用场景**:当闭包只需要读取环境变量的值,且希望避免所有权转移带来的开销时使用。
3. 按可变引用捕获
- 方式:通过在闭包参数前加 mut
关键字来按可变引用捕获环境变量。例如:
fn main() {
let mut num = 5;
let closure = || {
num += 1;
println!("The new value of num is: {}", num);
};
closure();
}
- **适用场景**:当闭包需要修改环境变量的值时使用。但要注意,同一时间只能有一个可变引用,以避免数据竞争。