MST
星途 面试题库

面试题:Rust move语义与闭包中的所有权转移

编写一个Rust函数,该函数接受一个闭包作为参数,闭包内部会操作一个具有复杂数据结构(如嵌套的结构体和向量)的对象。在函数调用过程中,展示如何合理利用move语义确保所有权的正确转移,同时避免内存泄漏和悬空指针问题,并详细说明闭包捕获变量的所有权机制在这个场景中的应用。
35.3万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义复杂数据结构
struct Inner {
    data: Vec<i32>
}

struct Outer {
    inner: Inner
}

// 接受闭包作为参数的函数
fn process_with_closure(closure: impl FnOnce(Outer) -> ()) {
    let outer = Outer {
        inner: Inner {
            data: vec![1, 2, 3]
        }
    };
    closure(outer);
}

fn main() {
    process_with_closure(|mut outer| {
        // 闭包中操作复杂数据结构
        outer.inner.data.push(4);
        println!("{:?}", outer.inner.data);
    });
}

所有权机制说明

  1. move语义:在process_with_closure(|mut outer| { ... })这一行,move关键字隐式地被使用。closure通过move语义获取了outer的所有权。这意味着outer的所有权从定义它的地方(process_with_closure函数内部)转移到了闭包内部。这样做确保了闭包可以安全地操作outer,因为outer的生命周期被限制在闭包的执行期间,避免了悬空指针问题。
  2. 避免内存泄漏:Rust的所有权系统确保了内存的正确释放。当闭包执行完毕后,outer及其内部的Inner结构体和Vec<i32>会按照Rust的内存管理规则被正确释放,不会发生内存泄漏。
  3. 闭包捕获变量的所有权:在这个场景中,闭包捕获了outer的所有权。由于使用了move语义,outer在闭包外部不再可用,闭包完全拥有outer。如果闭包被赋值给一个变量并在之后调用,outer的所有权转移到闭包内并在闭包调用时生效,整个生命周期管理由Rust编译器自动处理,确保了内存安全。