🔑
所有権と借用 — RustがGCなしでメモリを管理する仕組み
コンパイル時にメモリ安全性を保証するRustの核心ルール
C/C++はプログラマがメモリを直接管理する。ミスするとuse-after-free、double free、ダングリングポインタ — セキュリティ脆弱性の70%がここから生まれる(Microsoft統計)。Java/Go/PythonはGCで解決するが、GC一時停止とメモリオーバーヘッドがつく。
Rustは第3の方法を選んだ。コンパイラが所有権ルールを検査してメモリバグをコード記述時点で検出する。ランタイムコストはゼロ。
3つのルール
1. 値には所有者が1つだけ。 let s2 = s1;でs1の所有権がs2にムーブする。以降s1を使うとコンパイルエラー。
2. 借用は2種類。 &xは不変参照(複数同時可)、&mut xは可変参照(1つのみ)。両方同時には使えない。
3. 参照は所有者より長生きできない。 これがライフタイムルールで、ダングリングポインタを根本から遮断する。
最初に辛いこと
コンパイラのエラー頻度にメンタルが揺れる。特に構造体に参照を入れようとした時のライフタイム注釈要求は最初は壁に感じる。しかしこれは他言語で「ランタイムで爆発していたバグ」をコンパイル時に引き寄せただけだ。エラーの場所が変わっただけでバグの数が増えたわけではない。
キーポイント
1
全ての値に所有者が正確に1つ存在する
2
所有者がスコープを抜けると値が自動的にdropされる(RAII)
3
不変参照(&T)は複数同時可、可変参照(&mut T)は1つのみ
4
参照が有効な間、所有者は値を移動したり可変借用したりできない
5
コンパイラ(borrow checker)がこれらのルールを全て静的に検証する
メリット
- ✓ メモリバグがコンパイル時に検出される — ランタイムクラッシュではなくコンパイルエラー
- ✓ GCなし — ランタイムオーバーヘッドゼロ、予測可能な性能
- ✓ データレース防止 — コンパイラが同時可変アクセスを遮断
デメリット
- ✗ 学習曲線が急 — borrow checkerとの戦いが初期ハードル
- ✗ 自己参照構造体が基本的に不可能
- ✗ プロトタイピング速度がGC言語と比べて遅い
ユースケース
システムプログラミング — OSカーネル、ドライバでのメモリ安全性保証
Webサーバー — GC一時停止のない予測可能な応答時間
組み込み — ヒープ割り当てなしでスタックのみで動作するコード記述