m03-mutability
CRITICAL: Use for mutability issues. Triggers: E0596, E0499, E0502, cannot borrow as mutable, already borrowed as immutable, mut, &mut, interior mutability, Cell, RefCell, Mutex, RwLock, 可变性, 内部可变性, 借用冲突
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o m03-mutability.zip https://jpskill.com/download/9262.zip && unzip -o m03-mutability.zip && rm m03-mutability.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/9262.zip -OutFile "$d\m03-mutability.zip"; Expand-Archive "$d\m03-mutability.zip" -DestinationPath $d -Force; ri "$d\m03-mutability.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
m03-mutability.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
m03-mutabilityフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
可変性
レイヤー1: 言語の仕組み
中核となる問い
なぜこのデータは変更される必要があり、誰がそれを変更できるのか?
内部可変性を追加する前に、以下を理解してください。
- 可変性は本質的なものか、偶発的な複雑さか?
- 誰が可変性を制御すべきか?
- 可変性のパターンは安全か?
エラー → 設計の問い
| エラー | 単に言うのではなく | 代わりに問う |
|---|---|---|
| E0596 | "mut を追加" | これは本当に可変であるべきか? |
| E0499 | "借用を分割" | データ構造は正しいか? |
| E0502 | "スコープを分離" | なぜ両方の借用が必要なのか? |
| RefCell パニック | "try_borrow を使用" | ランタイムチェックは適切か? |
思考のきっかけ
可変性を追加する前に:
-
可変性は必要か?
- おそらく変換 → 新しい値を返す
- おそらくビルダー → 不変に構築する
-
誰が可変性を制御するか?
- 外部の呼び出し元 →
&mut T - 内部ロジック → 内部可変性
- 並行アクセス → 同期された可変性
- 外部の呼び出し元 →
-
スレッドのコンテキストは?
- シングルスレッド → Cell/RefCell
- マルチスレッド → Mutex/RwLock/Atomic
上流をたどる ↑
可変性の競合が解消されない場合:
E0499/E0502 (借用競合)
↑ 問い: データ構造は正しく設計されているか?
↑ 確認: m09-domain (データを分割すべきか?)
↑ 確認: m07-concurrency (async が関係しているか?)
| 解消されないエラー | たどる先 | 問い |
|---|---|---|
| 繰り返される借用競合 | m09-domain | データを再構築すべきか? |
| async 内の RefCell | m07-concurrency | Send/Sync は必要か? |
| Mutex デッドロック | m07-concurrency | ロックの設計は正しいか? |
下流をたどる ↓
設計から実装へ:
"&self から可変アクセスが必要"
↓ T: Copy → Cell<T>
↓ T: !Copy → RefCell<T>
"スレッドセーフな可変性が必要"
↓ 単純なカウンター → AtomicXxx
↓ 複雑なデータ → Mutex<T> または RwLock<T>
"共有された可変な状態が必要"
↓ シングルスレッド: Rc<RefCell<T>>
↓ マルチスレッド: Arc<Mutex<T>>
借用規則
常に、以下のいずれかを持つことができます。
├─ 複数の &T (不変の借用)
└─ または 1つの &mut T (可変の借用)
決して同時に両方を持つことはできません。
クイックリファレンス
| パターン | スレッドセーフ | ランタイムコスト | 使用場面 |
|---|---|---|---|
&mut T |
N/A | ゼロ | 排他的な可変アクセス |
Cell<T> |
いいえ | ゼロ | Copy 型、参照は不要 |
RefCell<T> |
いいえ | ランタイムチェック | Non-Copy、ランタイム借用が必要 |
Mutex<T> |
はい | ロック競合 | スレッドセーフな可変性 |
RwLock<T> |
はい | ロック競合 | 多数のリーダー、少数のライター |
Atomic* |
はい | 最小限 | 単純な型 (bool, usize) |
エラーコードリファレンス
| エラー | 原因 | 応急処置 |
|---|---|---|
| E0596 | 不変なものを可変として借用 | mut を追加するか、再設計する |
| E0499 | 複数の可変な借用 | コードフローを再構築する |
| E0502 | & が存在する間に &mut が存在する | 借用スコープを分離する |
内部可変性の決定
| シナリオ | 選択 |
|---|---|
| T: Copy, シングルスレッド | Cell<T> |
| T: !Copy, シングルスレッド | RefCell<T> |
| T: Copy, マルチスレッド | AtomicXxx |
| T: !Copy, マルチスレッド | Mutex<T> または RwLock<T> |
| 読み込みが多い、マルチスレッド | RwLock<T> |
| 単純なフラグ/カウンター | AtomicBool, AtomicUsize |
アンチパターン
| アンチパターン | なぜ悪いか | より良い方法 |
|---|---|---|
| RefCell をどこでも使用 | ランタイムパニック | 明確な所有権設計 |
| シングルスレッドに Mutex | 不要なオーバーヘッド | RefCell |
| RefCell パニックを無視 | デバッグが困難 | 処理するか、再構築する |
| ホットループ内でロック | パフォーマンスキラー | バッチ処理 |
関連スキル
| いつ | 参照 |
|---|---|
| スマートポインタの選択 | m02-resource |
| スレッド安全性 | m07-concurrency |
| データ構造の設計 | m09-domain |
| アンチパターン | m15-anti-pattern |
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Mutability
Layer 1: Language Mechanics
Core Question
Why does this data need to change, and who can change it?
Before adding interior mutability, understand:
- Is mutation essential or accidental complexity?
- Who should control mutation?
- Is the mutation pattern safe?
Error → Design Question
| Error | Don't Just Say | Ask Instead |
|---|---|---|
| E0596 | "Add mut" | Should this really be mutable? |
| E0499 | "Split borrows" | Is the data structure right? |
| E0502 | "Separate scopes" | Why do we need both borrows? |
| RefCell panic | "Use try_borrow" | Is runtime check appropriate? |
Thinking Prompt
Before adding mutability:
-
Is mutation necessary?
- Maybe transform → return new value
- Maybe builder → construct immutably
-
Who controls mutation?
- External caller →
&mut T - Internal logic → interior mutability
- Concurrent access → synchronized mutability
- External caller →
-
What's the thread context?
- Single-thread → Cell/RefCell
- Multi-thread → Mutex/RwLock/Atomic
Trace Up ↑
When mutability conflicts persist:
E0499/E0502 (borrow conflicts)
↑ Ask: Is the data structure designed correctly?
↑ Check: m09-domain (should data be split?)
↑ Check: m07-concurrency (is async involved?)
| Persistent Error | Trace To | Question |
|---|---|---|
| Repeated borrow conflicts | m09-domain | Should data be restructured? |
| RefCell in async | m07-concurrency | Is Send/Sync needed? |
| Mutex deadlocks | m07-concurrency | Is the lock design right? |
Trace Down ↓
From design to implementation:
"Need mutable access from &self"
↓ T: Copy → Cell<T>
↓ T: !Copy → RefCell<T>
"Need thread-safe mutation"
↓ Simple counters → AtomicXxx
↓ Complex data → Mutex<T> or RwLock<T>
"Need shared mutable state"
↓ Single-thread: Rc<RefCell<T>>
↓ Multi-thread: Arc<Mutex<T>>
Borrow Rules
At any time, you can have EITHER:
├─ Multiple &T (immutable borrows)
└─ OR one &mut T (mutable borrow)
Never both simultaneously.
Quick Reference
| Pattern | Thread-Safe | Runtime Cost | Use When |
|---|---|---|---|
&mut T |
N/A | Zero | Exclusive mutable access |
Cell<T> |
No | Zero | Copy types, no refs needed |
RefCell<T> |
No | Runtime check | Non-Copy, need runtime borrow |
Mutex<T> |
Yes | Lock contention | Thread-safe mutation |
RwLock<T> |
Yes | Lock contention | Many readers, few writers |
Atomic* |
Yes | Minimal | Simple types (bool, usize) |
Error Code Reference
| Error | Cause | Quick Fix |
|---|---|---|
| E0596 | Borrowing immutable as mutable | Add mut or redesign |
| E0499 | Multiple mutable borrows | Restructure code flow |
| E0502 | &mut while & exists | Separate borrow scopes |
Interior Mutability Decision
| Scenario | Choose |
|---|---|
| T: Copy, single-thread | Cell<T> |
| T: !Copy, single-thread | RefCell<T> |
| T: Copy, multi-thread | AtomicXxx |
| T: !Copy, multi-thread | Mutex<T> or RwLock<T> |
| Read-heavy, multi-thread | RwLock<T> |
| Simple flags/counters | AtomicBool, AtomicUsize |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| RefCell everywhere | Runtime panics | Clear ownership design |
| Mutex for single-thread | Unnecessary overhead | RefCell |
| Ignore RefCell panic | Hard to debug | Handle or restructure |
| Lock inside hot loop | Performance killer | Batch operations |
Related Skills
| When | See |
|---|---|
| Smart pointer choice | m02-resource |
| Thread safety | m07-concurrency |
| Data structure design | m09-domain |
| Anti-patterns | m15-anti-pattern |