面试题答案
一键面试- 理解
Deref
和DerefMut
Deref
允许结构体像引用一样使用,当解引用一个实现了Deref
的结构体时,*
操作符会自动调用Deref::deref
方法。DerefMut
则允许对结构体进行可变解引用,*
操作符会调用DerefMut::deref_mut
方法。
- 代码示例
- 首先定义嵌套的结构体层次:
struct Inner {
data: i32,
}
struct Middle {
inner: Inner,
}
struct Outer {
middle: Middle,
}
- 为
Inner
、Middle
和Outer
实现Deref
和DerefMut
:
use std::ops::{Deref, DerefMut};
impl Deref for Inner {
type Target = i32;
fn deref(&self) -> &Self::Target {
&self.data
}
}
impl DerefMut for Inner {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data
}
}
impl Deref for Middle {
type Target = Inner;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for Middle {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl Deref for Outer {
type Target = Middle;
fn deref(&self) -> &Self::Target {
&self.middle
}
}
impl DerefMut for Outer {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.middle
}
}
- 使用可变访问:
fn main() {
let mut outer = Outer {
middle: Middle {
inner: Inner {
data: 42,
},
},
};
// 可变访问内部数据
let inner_ref: &mut i32 = &mut *outer;
*inner_ref = 43;
println!("{}", outer);
}
- 遵循借用规则
- 在上述代码中,通过
DerefMut
实现了对嵌套结构体中内部数据的可变访问。Rust的借用规则保证了在任何时刻,要么只能有一个可变引用(可变借用),要么只能有多个不可变引用(不可变借用),但不能同时存在。 - 例如,如果在获取
inner_ref
可变引用后,尝试再获取一个对outer
的不可变引用,编译器会报错:
- 在上述代码中,通过
fn main() {
let mut outer = Outer {
middle: Middle {
inner: Inner {
data: 42,
},
},
};
let inner_ref: &mut i32 = &mut *outer;
// 下面这行代码会报错,因为已经有了对`outer`的可变引用`inner_ref`
let outer_ref: &Outer = &outer;
}
- 编译器会提示类似于“cannot borrow
outer
as immutable because it is also borrowed as mutable”的错误,从而防止数据竞争和未定义行为。
总结:通过正确实现Deref
和DerefMut
trait,并遵循Rust的借用规则,在嵌套结构体层次中使用DerefMut
进行可变访问时可以避免数据竞争和未定义行为。