m01-ownership について
m01-ownershipは、Rust開発者向けに所有権とライフタイムの問題を考える学習スキルです。コンパイラーエラーを設計上の問いに置き換え、実装パターンにつなげます。
主な機能
- 01所有権とライフタイムの設計問い
- 02Rustエラーコードのガイド
- 03ムーブ、借用、クローンの参照
- 04RcとArcによる共有所有権
- 05関連する設計スキルへの案内
活用シーン
- 01借用チェッカーのエラー調査
- 02データをムーブするか借用するかの選択
- 03クローンが必要かの検討
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ actionbook/ rust-skills --skill m01-ownershipインストール後、Claude Code で/m01-ownershipを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
comparison.mdexamples/best-practices.mdpatterns/common-errors.mdlifetime-patterns.md詳細
所有権とライフタイム
レイヤー 1:言語の仕組み
核となる問い
このデータは誰が所有し、どのくらいの期間保持すべきでしょうか?
所有権エラーを修正する前に、データの役割を理解してください。
- 共有されるものですか、それとも排他的なものですか?
- 短期間だけ使うものですか、それとも長期間使うものですか?
- 変換されるものですか、それとも読み取られるだけですか?
エラー → 設計上の問い
| エラー | すぐに言わないこと | 代わりに問うこと |
|---|---|---|
| E0382 | 「クローンしてください」 | このデータは誰が所有すべきでしょうか? |
| E0597 | 「ライフタイムを延ばしてください」 | スコープの境界は適切でしょうか? |
| E0506 | 「先に借用を終わらせてください」 | 変更は別の場所で行うべきでしょうか? |
| E0507 | 「ムーブする前にクローンしてください」 | なぜ参照からムーブしようとしているのでしょうか? |
| E0515 | 「所有値を返してください」 | 呼び出し元がデータを所有すべきでしょうか? |
| E0716 | 「変数に束縛してください」 | なぜ一時値なのでしょうか? |
| E0106 | 「'a を追加してください」 | 実際のライフタイムの関係はどうなっていますか? |
思考のためのプロンプト
所有権エラーを修正する前に、次のことを確認してください。
-
このデータはドメインでどのような役割を果たしますか?
- エンティティ(一意のアイデンティティ)→ 所有する
- 値オブジェクト(相互に置き換え可能)→ クローン/コピーしても問題ありません
- 一時値(計算結果)→ 構造の見直しが必要かもしれません
-
所有権の設計は意図的ですか?
- 設計どおり → 制約の範囲内で対応します
- 意図しないもの → 再設計を検討します
-
症状を直しますか、それとも再設計しますか?
- ストライク 3(3 回目の試行)の場合 → レイヤー 2 に進みます
上位をたどる ↑
エラーが続く場合は、設計レイヤーまでさかのぼります。
E0382 (moved value)
↑ Ask: What design choice led to this ownership pattern?
↑ Check: m09-domain (is this Entity or Value Object?)
↑ Check: domain-* (what constraints apply?)
| 続くエラー | たどり先 | 問い |
|---|---|---|
| E0382 が繰り返し発生 | m02-resource | 共有に Arc/Rc を使うべきでしょうか? |
| E0597 が繰り返し発生 | m09-domain | スコープの境界は適切な場所にありますか? |
| E0506/E0507 | m03-mutability | 内部可変性を使うべきでしょうか? |
下位をたどる ↓
設計上の決定から実装へ進みます。
"Data needs to be shared immutably"
↓ Use: Arc<T> (multi-thread) or Rc<T> (single-thread)
"Data needs exclusive ownership"
↓ Use: move semantics, take ownership
"Data is read-only view"
↓ Use: &T (immutable borrow)
クイックリファレンス
| パターン | 所有権 | コスト | 使用する場面 |
|---|---|---|---|
| ムーブ | 移譲 | ゼロ | 呼び出し元がデータを必要としない |
&T | 借用 | ゼロ | 読み取り専用でアクセスする |
&mut T | 排他的な借用 | ゼロ | 変更する必要がある |
clone() | 複製 | 割り当て+コピー | 実際にコピーが必要 |
Rc<T> | 共有(単一) | 参照カウント | 単一スレッドで共有する |
Arc<T> | 共有(複数) | アトミックな参照カウント | 複数スレッドで共有する |
Cow<T> | 書き込み時にクローン | 変更時に割り当て | 変更する可能性がある |
エラーコードリファレンス
| エラー | 原因 | すぐにできる修正 |
|---|---|---|
| E0382 | 値がムーブされた | クローンする、参照を使う、または所有権を再設計する |
| E0597 | 参照が所有者より長く存続する | 所有者のスコープを延ばす、または構造を見直す |
| E0506 | 借用中に代入する | 変更の前に借用を終わらせる |
| E0507 | 借用中の値をムーブする | クローンする、または参照を使う |
| E0515 | ローカル変数への参照を返す | 所有値を返す |
| E0716 | 一時値が破棄された | 変数に束縛する |
| E0106 | ライフタイムが不足している | 'a 注釈を追加する |
アンチパターン
| アンチパターン | 問題点 | より良い方法 |
|---|---|---|
あらゆる場所で .clone() を使う | 設計上の問題を覆い隠します | 所有権を適切に設計する |
| 借用チェッカーに逆らう | 複雑さが増します | コンパイラーに沿って実装する |
何にでも 'static を使う | 柔軟性が制限されます | 適切なライフタイムを使う |
Box::leak でリークさせる | メモリーリークが発生します | ライフタイムを適切に設計する |
関連スキル
| 場面 | 参照先 |
|---|---|
| スマートポインターが必要 | m02-resource |
| 内部可変性が必要 | m03-mutability |
| データがドメインエンティティ | m09-domain |
| 所有権の概念を学ぶ | m14-mental-model |
コメント
Markdown 対応