所有権と借用

Rust のメモリ管理モデルで、GC なしでメモリ安全性を保証する仕組み

Rustメモリ管理

所有権と借用とは

所有権 (Ownership) と借用 (Borrowing) は、Rust のメモリ管理モデルで、ガベージコレクション (GC) なしでメモリ安全性をコンパイル時に保証する。詳細は「Rust」の用語を参照。

所有権の 3 つのルール

  1. 各値には所有者が 1 つだけ
  2. 所有者がスコープを抜けると値は自動的に解放 (drop)
  3. 所有権は移動 (ムーブ) できる
let s1 = String::from("hello");
let s2 = s1;        // 所有権が s1 → s2 に移動
// println!("{}", s1); // ❌ コンパイルエラー: s1 はもう使えない
println!("{}", s2);   // ✅ OK

借用 (参照)

fn print_length(s: &String) {  // 不変参照 (借用)
    println!("Length: {}", s.len());
}

let s = String::from("hello");
print_length(&s);  // 借用: 所有権は移動しない
println!("{}", s);  // ✅ まだ使える

不変参照 vs 可変参照

let mut s = String::from("hello");

// 不変参照: 複数同時に可能
let r1 = &s;
let r2 = &s;

// 可変参照: 1 つだけ (不変参照と同時に持てない)
let r3 = &mut s;
r3.push_str(" world");
ルール 説明
不変参照は複数同時に可能 &T は何個でも OK
可変参照は 1 つだけ &mut T は 1 つだけ
不変と可変は同時に持てない データ競合を防止

ライフタイム

// ライフタイム注釈: 参照の有効期間を明示
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

ライフタイムは「参照がどれだけの期間有効か」をコンパイラに伝える。ダングリングポインタ (解放済みメモリへの参照) を防ぐ。

なぜ重要か

所有権システムにより、Rust は以下をコンパイル時に防止する:

  • メモリリーク
  • ダングリングポインタ
  • データ競合
  • 二重解放

理論と実装の両面から学ぶなら関連書籍が参考になる。

関連用語