|
Derefトレイトを実装した構造体は、自動的に参照外しが行える。
つまり、「Dという、Derefトレイトを実装した構造体」が「Tという構造体」のデータを保持しているとき、D型の変数なのにTのメソッドを呼べる。
例えば、BoxはDerefトレイトを実装しているので、Box型の変数からBox内部のインスタンスのメソッドが呼べる。
struct MyStruct {}
impl MyStruct {
fn example(&self) {
print!("example");
}
}
fn main() {
let s: Box<MyStruct> = Box::new(MyStruct {});
s.example(); // sはBox型の変数なのに、Boxの中のMyStructのメソッドが直接呼び出せる
}
可変参照用にDerefMutというトレイトもある。[2025-08-22]
mutなメソッドを呼びたい場合は、DerefMutを実装する。
Derefを実装する例。[2025-08-22]
struct MyStruct;
impl MyStruct {
pub fn test1(&self) {
println!("MyStruct.test1()");
}
pub fn test3(&self) {
println!("MyStruct.test3()");
}
}
struct MyWrapper {
my_struct: MyStruct,
}
impl MyWrapper {
pub fn test2(&self) {
println!("MyWrapper.test2()");
}
pub fn test3(&self) {
println!("MyWrapper.test3()");
}
}
impl std::ops::Deref for MyWrapper {
type Target = MyStruct;
fn deref(&self) -> &Self::Target {
&self.my_struct
}
}
fn main() {
let w = MyWrapper {
my_struct: MyStruct {},
};
w.test1(); // DerefでMyStructを返すようになっているので、MyStructのメソッドが直接呼べる
w.test2();
w.test3(); // 同名のメソッドが両方にある場合は、MyWrapperのメソッドが呼ばれる
w.deref().test3(); // derefメソッドでMyStruct(の参照)が取れる
}