S-JIS[2024-10-04/2025-08-22] 変更履歴

Rust Derefトレイト

Ruststd::ops::Derefのメモ。


概要

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(の参照)が取れる
}

stdへ戻る / Rustへ戻る / 技術メモへ戻る
メールの送信先:ひしだま