MST

星途 面试题库

面试题:Rust中Deref和DerefMut在所有权和借用规则下的行为

在Rust中,当一个类型同时实现`Deref`和`DerefMut`时,在不同的借用场景下(例如不可变借用和可变借用),它们是如何协同工作的?请详细描述,并编写一段代码展示在复杂借用情况下`Deref`和`DerefMut`的正确使用方式,比如在一个函数中同时涉及对实现了这两个trait的类型的不可变和可变操作。
17.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

1. DerefDerefMut 协同工作原理

  • 不可变借用:当对实现了 Deref trait 的类型进行不可变借用时,Rust 会自动调用 Deref::deref 方法,将该类型转换为其内部引用的类型。这使得我们可以像操作内部类型一样操作外部类型,例如访问内部类型的方法和字段。
  • 可变借用:当对实现了 DerefMut trait 的类型进行可变借用时,Rust 会调用 DerefMut::deref_mut 方法,提供对内部类型的可变引用。这允许我们修改内部类型的数据。
  • 协同关系DerefMutDeref 的超集,即所有实现 DerefMut 的类型也必须实现 Deref。这是因为可变引用可以在需要时当作不可变引用使用,但反之则不行。

2. 代码示例

use std::ops::{Deref, DerefMut};

// 定义一个包含内部数据的结构体
struct MyBox<T> {
    data: T,
}

// 实现 Deref trait,提供不可变访问
impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.data
    }
}

// 实现 DerefMut trait,提供可变访问
impl<T> DerefMut for MyBox<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.data
    }
}

// 定义一个函数,展示复杂借用情况下的使用
fn complex_usage() {
    let mut my_box = MyBox { data: String::from("hello") };

    // 不可变借用
    let ref_to_box: &MyBox<String> = &my_box;
    let len = ref_to_box.len(); // 自动调用 Deref::deref
    println!("Length of string: {}", len);

    // 可变借用
    let mut_mut_ref = &mut my_box;
    mut_mut_ref.push_str(", world"); // 自动调用 DerefMut::deref_mut
    println!("Modified string: {}", my_box);
}

你可以通过调用 complex_usage 函数来展示在复杂借用情况下 DerefDerefMut 的正确使用。这个函数中,首先对 MyBox 进行不可变借用并访问其内部 String 的方法,然后进行可变借用并修改内部 String 的内容。