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 を作成しました!"); }