MST

星途 面试题库

面试题:Rust闭包基础使用及捕获规则

请解释Rust中闭包的定义,如何声明一个闭包?并举例说明闭包对环境变量的三种捕获方式(按值、按可变引用、按不可变引用)及其适用场景。
34.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust中闭包的定义

闭包是可以捕获其所在环境的匿名函数。它可以作为值进行传递,并且可以在定义它的作用域之外调用。

声明闭包

闭包使用 || 语法声明,|| 之前为参数列表,之后为函数体。例如:

let closure = |x| x + 1;

这里定义了一个接收一个参数 x 并返回 x + 1 的闭包,并将其赋值给变量 closure

闭包对环境变量的三种捕获方式及其适用场景

  1. 按值捕获
    • 方式:闭包默认按值捕获环境中的变量。例如:
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();
}
- **适用场景**:当闭包需要修改环境变量的值时使用。但要注意,同一时间只能有一个可变引用,以避免数据竞争。