# レクチャー進行メモ & 質問対策

## タイムテーブル（60分）

| 時間 | セクション | やること |
|------|----------|--------|
| 0:00-0:02 | オープニング | タイトル・自己紹介・ゴール共有 |
| 0:02-0:05 | ロードマップ | 全体像を見せる。質問はいつでもOKと伝える |
| 0:05-0:25 | 所有権と借用 | ライブデモ中心。例01→02→03の順で体感 |
| 0:25-0:45 | トレイト抽象化 | コードリーディング中心。例04を動かす |
| 0:45-0:57 | 非同期の地雷 | ライブデモ。例05→06、07→08、09 |
| 0:57-1:00 | Claude Code / まとめ | 心構えを共有して締める |

---

## セクション別の進め方

### セクション1: 所有権と借用（20分）

**スライド4「このコード、なぜ通らない？」**
- コードを見せて「何が起きると思う？」と聞く（30秒待つ）
- `cargo check --example 01_broken` をライブ実行
- エラーメッセージを一緒に読む：「Rustのコンパイラは親切。エラー番号もhelp文もある」
- 「コンパイラの提案通りに直してみよう」→ 次へ

**スライド5「通る、でも…」**
- `cargo run --example 02_naive_fix` を起動
- `curl localhost:3000` を3回叩く → 毎回 count:1
- 「コンパイルが通る ≠ 正しく動く。これがRustの面白いところ」
- 「じゃあどうする？」と問いかけて次へ

**スライド6「Arc<Mutex<T>>」**
- `cargo run --example 03_shared_state` を起動
- `curl localhost:3000` を3回叩く → count:1, 2, 3
- Arc/Mutex/Clone の3つのキーワードを説明
- 「State extractorがCloneを要求する → Arcが自然な選択」

**想定質問:**
- 「RwLockとの違いは？」→ 読み取りが多ければRwLockが有利。最初はMutexで十分、ボトルネックになったら変える
- 「clone()のコストは？」→ Arcのcloneは参照カウントのアトミック加算だけ。データのコピーではない
- 「Mutexのロック中にpanicしたら？」→ poisonedになる。unwrap()で検出。本番ではpoisonの処理を書く

### セクション2: トレイト抽象化（20分）

**スライド8「traitでインターフェースを切る」**
- 例04のコードを一緒に読む（動かしながら）
- `trait UserRepository` → GoのinterfaceやTypeScriptのinterfaceと比較
- `Send + Sync` 境界 → 「Axumで使うために必要」と一言
- InMemoryUserRepoの実装を見せる → テストで使える

**スライド9「dyn vs impl」**
- 両方のコードを比較
- チーム開発では dyn Trait を推奨する理由を3つ挙げる
- 「パフォーマンスが問題になったら計測してから変える」

**想定質問:**
- 「async_traitはいつまで必要？」→ Rust 1.75からRPITITで一部対応。だがdyn Traitではまだ必要
- 「Box<dyn Trait>とArc<dyn Trait>の違いは？」→ スレッド間共有が必要ならArc。Axumでは基本Arc
- 「テストはどう書く？」→ InMemoryRepoを作ってハンドラに渡すだけ。DBのセットアップ不要

### セクション3: 非同期の地雷（15分）

**地雷① Send（5分）**
- `cargo check --example 05_send_error` → エラーを見せる
- 「Rc → Arc に変えるだけ」を実演
- `cargo run --example 06_send_fix` → 動く

**地雷② 'static（5分）**
- `cargo check --example 07_static_error` → エラーを見せる
- 「move を付けるだけ」を実演
- 「moveすると元の変数は使えなくなる。必要なら事前にclone()」

**地雷③ ブロッキング（5分）**
- `cargo run --example 09_blocking` を起動
- 2つのターミナルで同時に /slow と /fast にアクセス
- /fast が待たされることを確認 → 「これがブロッキングの怖さ」
- コード内の slow_handler を slow_handler_fixed に変えて再実行

**想定質問:**
- 「全部Arcにすればいいのでは？」→ シングルスレッドならRcの方が軽い。Axumでは基本Arcだが文脈による
- 「spawn_blockingのスレッドプールのサイズは？」→ デフォルト512。`tokio::runtime::Builder`で変更可能
- 「async fnの中でstd::fs使っちゃダメなの？」→ ファイルが小さくてレイテンシが許容できるなら実用上は問題ないこともある。ただし原則はtokio::fsを使う

---

## 全体を通した想定質問

**Q: エラーハンドリングは？（unwrap多すぎない？）**
→ 今日のスコープ外。次回のテーマ候補。本番では `?` + `thiserror` / `anyhow` を使う。Axumでは `IntoResponse` を実装したエラー型を作る。

**Q: ライフタイム注釈（'a）はいつ必要？**
→ Axumのハンドラレベルではほぼ書かない。自分で参照を返す関数を書くときに必要になる。ハマったら個別対応で十分。

**Q: Claude Codeが生成したコードをそのまま使っていい？**
→ コンパイルが通るかは cargo check で即確認。ロジックの正しさはテストで担保。型シグネチャ（特にArc/Mutex/dyn Trait）は意図を理解してから採用する。

**Q: マクロは理解しなくていい？**
→ 使うけど書かない段階なら後回し。`#[tokio::main]`, `#[derive(...)]`, `route!` などは「おまじない」でOK。

**Q: Goや TypeScriptと比べてRustの学習コストは？**
→ 所有権の概念は最初の壁。ただしコンパイラが教えてくれるので、エラーメッセージを読む習慣があれば想像より早く慣れる。今日やった3つの壁を超えれば、Axumでの開発は十分回せる。
