所有権と借用
Rust のメモリ管理モデルで、GC なしでメモリ安全性を保証する仕組み
Rustメモリ管理
所有権と借用とは
所有権 (Ownership) と借用 (Borrowing) は、Rust のメモリ管理モデルで、ガベージコレクション (GC) なしでメモリ安全性をコンパイル時に保証する。詳細は「Rust」の用語を参照。
所有権の 3 つのルール
- 各値には所有者が 1 つだけ
- 所有者がスコープを抜けると値は自動的に解放 (drop)
- 所有権は移動 (ムーブ) できる
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 は以下をコンパイル時に防止する:
- メモリリーク
- ダングリングポインタ
- データ競合
- 二重解放
理論と実装の両面から学ぶなら関連書籍が参考になる。