MST

星途 面试题库

面试题:Rust引用与所有权转移的复杂场景分析

考虑这样一个场景,有一个结构体`Container`,它包含一个`Vec<i32>`。现在有一个函数`split`,它接收`Container`的可变引用,并根据某个条件将`Vec<i32>`分割成两个`Vec<i32>`,分别存储在两个新的结构体`SubContainer`中。请编写代码实现这个过程,并详细说明在这个过程中引用、所有权的变化以及如何避免借用检查错误。
29.3万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义 SubContainer 结构体
struct SubContainer {
    data: Vec<i32>,
}

// 定义 Container 结构体
struct Container {
    data: Vec<i32>,
}

// split 函数,接收 Container 的可变引用,根据某个条件分割数据
fn split(container: &mut Container) -> (SubContainer, SubContainer) {
    // 这里简单以数据长度的一半作为分割条件
    let mid = container.data.len() / 2;
    let (left, right) = container.data.split_at_mut(mid);

    (
        SubContainer { data: left.to_vec() },
        SubContainer { data: right.to_vec() },
    )
}

引用、所有权变化及避免借用检查错误说明:

  1. 引用
    • split 函数接收 Container 的可变引用 &mut Container,这意味着函数可以修改 Container 实例内部的数据,但不会获取所有权。
  2. 所有权
    • Container 实例原本拥有 Vec<i32> 的所有权。
    • split 函数中,通过 split_at_mut 方法对 Vec<i32> 进行了分割。这个方法返回两个可变切片 &mut [i32],但并没有改变 Vec<i32> 的所有权。
    • 随后,通过 to_vec 方法将切片转换为新的 Vec<i32>,新的 Vec<i32>SubContainer 结构体拥有。此时,原始 Container 中的 Vec<i32> 数据被转移到了两个新的 SubContainer 实例中,Container 不再拥有 Vec<i32> 的所有权。
  3. 避免借用检查错误
    • 在 Rust 中,借用检查器确保同一时间内,一个资源要么有一个可变引用(可写),要么有多个不可变引用(可读),但不能同时存在可变和不可变引用。
    • 在这个例子中,通过 split_at_mut 方法获取的两个可变切片 leftright 是对 container.data 的唯一访问方式,不会出现同时存在其他对 container.data 的引用的情况,从而避免了借用检查错误。同时,to_vec 方法消耗了切片,进一步确保不会出现悬空引用等问题。