注意: 最新版のドキュメントをご覧ください。この第1版ドキュメントは古くなっており、最新情報が反映されていません。リンク先のドキュメントが現在の Rust の最新のドキュメントです。

Drop

トレイトについて学びましたので、Rustの標準ライブラリによって提供されている具体的なトレイト Drop について説明しましょう。 Drop トレイトは値がスコープ外になった時にコードを実行する方法を提供します。

struct HasDrop; impl Drop for HasDrop { fn drop(&mut self) { println!("Dropping!"); } } fn main() { let x = HasDrop; // do stuff // いくつかの処理 // } // x goes out of scope here } // x はここでスコープ外になります
struct HasDrop;

impl Drop for HasDrop {
    fn drop(&mut self) {
        println!("Dropping!");
    }
}

fn main() {
    let x = HasDrop;

    // いくつかの処理

} // x はここでスコープ外になります

xmain() の終わりでスコープ外になった時、 Drop のコードが実行されます。 Drop にはメソッドは1つだけあり、それもまた drop() と呼ばれます。 ミュータブルな self への参照を引数に取ります。

これだけです! Drop のメカニズムは非常にシンプルですが、少しばかり注意があります。 たとえば、値がドロップされる順序は、それらが定義された順序と反対の順序になります。

struct Firework { strength: i32, } impl Drop for Firework { fn drop(&mut self) { println!("BOOM times {}!!!", self.strength); } } fn main() { let firecracker = Firework { strength: 1 }; let tnt = Firework { strength: 100 }; }
struct Firework {
    strength: i32,
}

impl Drop for Firework {
    fn drop(&mut self) {
        println!("BOOM times {}!!!", self.strength);
    }
}

fn main() {
    let firecracker = Firework { strength: 1 };
    let tnt = Firework { strength: 100 };
}

このコードは以下のように出力します。

BOOM times 100!!!
BOOM times 1!!!

tntfirecracker (爆竹)が鳴る前に爆発してしまいました。 これはTNTが定義されたのは爆竹よりも後だったためです。 ラストイン・ファーストアウトです。

Drop は何をするのに向いているのでしょうか? 一般的に Dropstruct に関連付けられているリソースのクリーンアップに使われます。 たとえば Arc<T> は参照カウントを行う型です。 Drop が呼ばれると、参照カウントがデクリメントされ、もし参照の合計数が0になっていたら、内包している値がクリーンアップされます。