MST
星途 面试题库

面试题:Rust函数返回复杂数据结构的所有权处理

假设有一个结构体`MyStruct`,包含一个`Vec<i32>`成员。编写一个函数,该函数创建并返回`MyStruct`实例。在函数调用后,调用者要能够安全地使用返回的结构体及其内部的`Vec<i32>`。请阐述在这个过程中所有权是如何转移和管理的,并且解释为什么这样处理是安全的。
49.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

以下是 Rust 代码实现:

struct MyStruct {
    data: Vec<i32>,
}

fn create_my_struct() -> MyStruct {
    MyStruct {
        data: vec![1, 2, 3],
    }
}

所有权转移和管理

  1. 函数内部
    • create_my_struct 函数内部,vec![1, 2, 3] 创建了一个 Vec<i32> 实例,它拥有分配在堆上的内存。
    • 然后 MyStruct 结构体实例被创建,其 data 成员接收了 Vec<i32> 的所有权。
  2. 函数返回
    • create_my_struct 函数返回 MyStruct 实例时,整个 MyStruct 实例的所有权被转移给调用者。这意味着调用者现在完全拥有 MyStruct 实例及其内部的 Vec<i32>

安全性解释

  1. 内存安全
    • Rust 的所有权系统确保在任何时刻,堆上的内存只有一个所有者。当 create_my_struct 函数返回 MyStruct 实例时,之前在函数内创建的 Vec<i32> 的所有权被转移给调用者。当调用者不再使用 MyStruct 实例时,MyStruct 的析构函数会被调用,进而 Vec<i32> 的析构函数也会被调用,释放堆上的内存。这避免了内存泄漏和悬空指针的问题。
  2. 数据一致性
    • 由于同一时间只有一个所有者,不存在多个地方同时尝试修改 Vec<i32> 数据的情况,从而保证了数据的一致性。如果在函数返回后,原函数内部还能访问 Vec<i32>,就可能出现数据竞争等问题。但 Rust 的所有权规则阻止了这种情况发生,使得代码在多线程环境下也能保持安全。