MST

星途 面试题库

面试题:Rust闭包捕获变量机制基础

在Rust中,闭包捕获变量有哪几种方式?请举例说明每种捕获方式是如何影响变量所有权和生命周期的。
16.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

在Rust中,闭包捕获变量有三种方式:按值捕获、按可变引用捕获和按不可变引用捕获。以下分别举例说明它们对变量所有权和生命周期的影响:

按值捕获

闭包通过move语义按值捕获变量,这意味着变量的所有权被转移到闭包中。一旦闭包按值捕获了变量,外部作用域就不能再使用该变量。

fn main() {
    let num = 5;
    let closure = move || {
        println!("The number is: {}", num);
    };
    // 这里不能再使用num,因为所有权已转移到闭包中
    // println!("num: {}", num); // 这行会编译错误
    closure();
}

在上述例子中,num的所有权被转移到闭包closure中,所以在闭包定义之后,num在外部作用域不再可用。闭包的生命周期和num的生命周期绑定在一起,只要闭包存在,num就会一直存在。

按可变引用捕获

闭包可以按可变引用捕获变量,这样闭包可以修改捕获的变量。但在闭包捕获期间,外部作用域不能再使用该可变引用。

fn main() {
    let mut num = 5;
    let closure = || {
        num += 1;
        println!("The number is: {}", num);
    };
    // 这里不能再对num进行可变借用,因为闭包已经可变借用了num
    // num += 2; // 这行会编译错误
    closure();
    println!("num: {}", num);
}

在这个例子中,闭包closure按可变引用捕获了num,因此在闭包定义之后,外部作用域不能再对num进行可变借用。闭包的生命周期和对num的可变借用的生命周期一致,只要闭包存在,这个可变借用就存在。

按不可变引用捕获

闭包可以按不可变引用捕获变量,闭包可以读取但不能修改捕获的变量。同时,外部作用域仍然可以使用该变量。

fn main() {
    let num = 5;
    let closure = || {
        println!("The number is: {}", num);
    };
    println!("num: {}", num);
    closure();
}

在这个例子中,闭包closure按不可变引用捕获了num,外部作用域仍然可以使用num。闭包的生命周期和对num的不可变借用的生命周期一致,只要闭包存在,这个不可变借用就存在。