Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

RAII

Rust の変数は、スタック上にデータを保持するだけではありません。リソースも_所有_します。たとえば、Box<T> はヒープ上のメモリを所有します。Rust は RAII(Resource Acquisition Is Initialization)を強制するため、オブジェクトがスコープを抜けるたびに、そのデストラクタが呼び出され、所有しているリソースが解放されます。

この振る舞いにより、_リソースリーク_のバグから保護されるため、手動でメモリを解放したり、メモリリークを心配したりする必要は二度とありません!簡単な例を示します。

// raii.rs
fn create_box() {
    // ヒープ上に整数を割り当てる
    let _box1 = Box::new(3i32);

    // ここで `_box1` は破棄され、メモリが解放される
}

fn main() {
    // ヒープ上に整数を割り当てる
    let _box2 = Box::new(5i32);

    // ネストしたスコープ:
    {
        // ヒープ上に整数を割り当てる
        let _box3 = Box::new(4i32);

        // ここで `_box3` は破棄され、メモリが解放される
    }

    // 遊びでたくさんの Box を作成する
    // 手動でメモリを解放する必要はない!
    for _ in 0u32..1_000 {
        create_box();
    }

    // ここで `_box2` は破棄され、メモリが解放される
}

もちろん、valgrind を使ってメモリエラーを再確認できます。

$ rustc raii.rs && valgrind ./raii
==26873== Memcheck, a memory error detector
==26873== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26873== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==26873== Command: ./raii
==26873==
==26873==
==26873== HEAP SUMMARY:
==26873==     in use at exit: 0 bytes in 0 blocks
==26873==   total heap usage: 1,013 allocs, 1,013 frees, 8,696 bytes allocated
==26873==
==26873== All heap blocks were freed -- no leaks are possible
==26873==
==26873== For counts of detected and suppressed errors, rerun with: -v
==26873== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

ここにリークはありません!

デストラクタ

Rust におけるデストラクタの概念は、Drop トレイトによって提供されます。リソースがスコープを抜けるときに、デストラクタが呼び出されます。このトレイトはすべての型に実装する必要はありません。独自のデストラクタロジックが必要な場合にのみ、自分の型に実装してください。

以下の例を実行して、Drop トレイトがどのように動作するか確認してください。main 関数内の変数がスコープを抜けると、カスタムデストラクタが呼び出されます。

struct ToDrop;

impl Drop for ToDrop {
    fn drop(&mut self) {
        println!("ToDrop がドロップされます");
    }
}

fn main() {
    let x = ToDrop;
    println!("ToDrop を作成しました!");
}

関連項目:

Box