m14-mental-model について
m14-mental-modelは、Rustを学ぶ人や説明する人向けの概念ガイドです。たとえ話とよくある誤解の解説を通じて、所有権、借用、ライフタイム、Rustの安全性を理解しやすくします。
主な機能
- 01たとえ話によるRust概念の説明
- 02所有権、ムーブ、借用の解説
- 03ライフタイムとスマートポインターの説明
- 04他言語との考え方の違い
- 05誤解と学習段階の整理
活用シーン
- 01所有権や借用チェッカーのエラーを理解
- 02他言語の開発者にRustを説明
- 03Rust概念を学ぶ順序の計画
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ actionbook/ rust-skills --skill m14-mental-modelインストール後、Claude Code で/m14-mental-modelを入力して読み込まれたか確認します。
同梱ファイルpatterns/thinking-in-rust.md
詳細
メンタルモデル
レイヤー 2:設計上の選択
核となる問い
この Rust の概念を理解するうえで、適切な考え方は何でしょうか?
Rust を学んだり説明したりするときに考えること:
- 正しいメンタルモデルは何でしょうか?
- どのような誤解を避けるべきでしょうか?
- 理解に役立つたとえは何でしょうか?
主なメンタルモデル
| 概念 | メンタルモデル | たとえ |
|---|---|---|
| 所有権 | 唯一の鍵 | 家の鍵を持っているのは 1 人だけ |
| Move | 鍵の受け渡し | 自分の鍵を渡す |
&T | 読むために貸す | 本を貸す |
&mut T | 排他的な編集 | 文書を編集できるのは自分だけ |
ライフタイム 'a | 有効なスコープ | 「チケットの有効期限は…まで」 |
Box<T> | ヒープへのポインター | テレビのリモコン |
Rc<T> | 共有所有権 | 複数のリモコンがあり、最後の 1 つを切るとテレビが消える |
Arc<T> | スレッドセーフな Rc | どの部屋からでも使えるリモコン |
他の言語から移行する場合
| 使っていた言語 | 主な考え方の転換 |
|---|---|
| Java/C# | 値はデフォルトで参照ではなく、所有されます |
| C/C++ | コンパイラーが安全性のルールを強制します |
| Python/Go | GC がなく、破棄のタイミングが決定的です |
| 関数型言語 | 所有権によって変更可能性が安全になります |
| JavaScript | null はなく、代わりに Option を使います |
考えるための問い
Rust で混乱したときは、次の点を考えます。
-
所有権のモデルはどうなっていますか?
- このデータを所有しているのは誰ですか?
- このデータはいつまで存続しますか?
- 誰がアクセスできますか?
-
Rust はどのような保証を提供していますか?
- データ競合がない
- ダングリングポインターがない
- 解放後の使用がない
-
コンパイラーは何を伝えていますか?
- エラー = 安全性のルールへの違反
- 解決策 = ルールに沿って作業する
上にたどる ↑
理解を設計するには(レイヤー 2):
"Why can't I do X in Rust?"
↑ Ask: What safety guarantee would be violated?
↑ Check: m01-m07 for the rule being enforced
↑ Ask: What's the intended design pattern?
下にたどる ↓
実装については(レイヤー 1):
"I understand the concept, now how do I implement?"
↓ m01-ownership: Ownership patterns
↓ m02-resource: Smart pointer choice
↓ m07-concurrency: Thread safety
よくある誤解
| エラー | 誤ったモデル | 正しいモデル |
|---|---|---|
| E0382 move 後の使用 | GC が片付けてくれる | 所有権 = 唯一の鍵の受け渡し |
| E0502 借用の競合 | 複数の書き込みが可能 | 一度に書き込めるのは 1 つだけ |
| E0499 複数の可変借用 | エイリアスされた変更 | 変更には排他的アクセスが必要 |
| E0106 ライフタイムがない | スコープを無視している | 参照には有効なスコープがある |
E0507 &T から move できない | 暗黙的なクローン | 参照はデータを所有しない |
古い考え方
| 古い考え方 | より適切な考え方 |
|---|---|
| 「Rust は C++ に似ている」 | 所有権モデルが異なります |
| 「ライフタイムは GC である」 | コンパイル時に検証される有効なスコープです |
| 「Clone ですべて解決する」 | 所有権の構造を見直します |
| 「借用チェッカーと戦う」 | コンパイラーに沿って作業します |
「ルールを避けるために unsafe を使う」 | まず安全なパターンを理解します |
所有権の可視化
Stack Heap
+----------------+ +----------------+
| main() | | |
| s1 ─────────────────────> │ "hello" |
| | | |
| fn takes(s) { | | |
| s2 (moved) ─────────────> │ "hello" |
| } | | (s1 invalid) |
+----------------+ +----------------+
After move: s1 is no longer valid
参照の可視化
+----------------+
| data: String |────────────> "hello"
+----------------+
↑
│ &data (immutable borrow)
│
+------+------+
| reader1 reader2 (multiple OK)
+------+------+
+----------------+
| data: String |────────────> "hello"
+----------------+
↑
│ &mut data (mutable borrow)
│
+------+
| writer (only one)
+------+
学習の道筋
| 段階 | 学習内容 | スキル |
|---|---|---|
| 初級 | 所有権の基本 | m01-ownership, m14-mental-model |
| 中級 | スマートポインター、エラー処理 | m02, m06 |
| 上級 | 並行処理、unsafe | m07-concurrency, unsafe-checker |
| エキスパート | デザインパターン | m09-m15, domain-* |
関連スキル
| 場面 | 参照先 |
|---|---|
| 所有権エラー | m01-ownership |
| スマートポインター | m02-resource |
| 並行処理 | m07-concurrency |
| アンチパターン | m15-anti-pattern |
コメント
Markdown 対応