m04-zero-cost
重要:ジェネリクス、トレイト、ゼロコスト抽象化に使用します。トリガー:E0277、E0308、E0599、generic、trait、impl、dyn、where、単態化、静的ディスパッチ、動的ディスパッチ、impl Trait、トレイト境界未満足。
description の原文を見る
CRITICAL: Use for generics, traits, zero-cost abstraction. Triggers: E0277, E0308, E0599, generic, trait, impl, dyn, where, monomorphization, static dispatch, dynamic dispatch, impl Trait, trait bound not satisfied, 泛型, 特征, 零成本抽象, 单态化
SKILL.md 本文
ゼロコスト抽象化
レイヤー1: 言語メカニズム
コア質問
コンパイル時ポリモーフィズムと実行時ポリモーフィズムのどちらが必要か?
ジェネリクスとトレイトオブジェクトから選択する前に:
- 型はコンパイル時に既知か?
- 異種のコレクションが必要か?
- パフォーマンス上の優先順位は?
エラー → 設計質問
| エラー | 避けるべき対応 | 代わりに尋ねるべきこと |
|---|---|---|
| E0277 | 「トレイト境界を追加する」 | この抽象化は正しいレベルにあるか? |
| E0308 | 「型を修正する」 | 型は統一されるべきか、それとも異なるべきか? |
| E0599 | 「トレイトをインポートする」 | そのトレイトは正しい抽象化か? |
| E0038 | 「オブジェクト安全にする」 | 本当に動的ディスパッチが必要か? |
思考プロンプト
トレイト境界を追加する前に:
-
どのような抽象化が必要か?
- 同じ動作、異なる型 → トレイト
- 異なる動作、同じ型 → enum
- 抽象化が不要 → 具体的な型
-
型がいつ既知になるか?
- コンパイル時 → ジェネリクス(静的ディスパッチ)
- 実行時 → トレイトオブジェクト(動的ディスパッチ)
-
トレードオフの優先順位は?
- パフォーマンス → ジェネリクス
- コンパイル時間 → トレイトオブジェクト
- 柔軟性 → 状況による
上へ遡る ↑
型システムが反発するとき:
E0277 (トレイト境界が満たされていない)
↑ 尋ねる: 抽象化レベルは正しいか?
↑ 確認: m09-domain (どの動作が抽象化されているか?)
↑ 確認: m05-type-driven (newtype を使うべきか?)
| 継続的なエラー | 遡る先 | 質問 |
|---|---|---|
| 複雑なトレイト境界 | m09-domain | 抽象化は正しいか? |
| オブジェクト安全性の問題 | m05-type-driven | typestate が役立つか? |
| 型の爆発 | m10-performance | dyn のオーバーヘッドを受け入れるか? |
下へ降りる ↓
設計から実装へ:
「同じ動作を持つ型を抽象化する必要がある」
↓ 型がコンパイル時に既知 → impl Trait またはジェネリクス
↓ 型が実行時に決定 → dyn Trait
「異なる型のコレクションが必要」
↓ 閉じた集合 → enum
↓ 開いた集合 → Vec<Box<dyn Trait>>
「異なる型を返す必要がある」
↓ 同じ型 → impl Trait
↓ 異なる型 → Box<dyn Trait>
クイックリファレンス
| パターン | ディスパッチ | コードサイズ | 実行時コスト |
|---|---|---|---|
fn foo<T: Trait>() | 静的 | +肥大化 | ゼロ |
fn foo(x: &dyn Trait) | 動的 | 最小限 | vtable 参照 |
impl Trait 戻り値 | 静的 | +肥大化 | ゼロ |
Box<dyn Trait> | 動的 | 最小限 | 割り当て + vtable |
構文比較
// 静的ディスパッチ - 型はコンパイル時に既知
fn process(x: impl Display) { } // 引数位置
fn process<T: Display>(x: T) { } // 明示的なジェネリクス
fn get() -> impl Display { } // 戻り値位置
// 動的ディスパッチ - 型は実行時に決定
fn process(x: &dyn Display) { } // 参照
fn process(x: Box<dyn Display>) { } // 所有
エラーコード リファレンス
| エラー | 原因 | クイックフィックス |
|---|---|---|
| E0277 | 型がトレイトを実装していない | impl を追加するか、境界を変更 |
| E0308 | 型の不一致 | ジェネリクスパラメータを確認 |
| E0599 | メソッドが見つからない | use でトレイトをインポート |
| E0038 | トレイトがオブジェクト安全でない | ジェネリクスを使用するか、再設計 |
判断ガイド
| シナリオ | 選択 | 理由 |
|---|---|---|
| パフォーマンス重視 | ジェネリクス | 実行時コストゼロ |
| 異種コレクション | dyn Trait | 実行時に異なる型 |
| プラグインアーキテクチャ | dyn Trait | コンパイル時に未知の型 |
| コンパイル時間削減 | dyn Trait | 単態化が少ない |
| 小さく、既知の型セット | enum | 間接参照なし |
オブジェクト安全性
トレイトはオブジェクト安全であれば:
Self: Sized境界を持たないSelfを返さない- ジェネリックメソッドを持たない
where Self: Sizedを非オブジェクト安全なメソッドに使用
アンチパターン
| アンチパターン | 問題点 | より良い方法 |
|---|---|---|
| すべてをジェネリック化 | コンパイル時間、複雑さ | 可能な限り具体的な型 |
既知の型に dyn を使用 | 不要な間接参照 | ジェネリクス |
| 複雑なトレイト階層 | 理解が困難 | よりシンプルな設計 |
| オブジェクト安全性を無視 | 柔軟性の制限 | 必要に応じて dyn 計画 |
関連スキル
| のとき | 参照先 |
|---|---|
| 型駆動設計 | m05-type-driven |
| ドメイン抽象化 | m09-domain |
| パフォーマンスに関する懸念 | m10-performance |
| Send/Sync 境界 | m07-concurrency |
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- k1-c
- リポジトリ
- k1-c/linear-tui
- ライセンス
- MIT
- 最終更新
- 2026/3/5
Source: https://github.com/k1-c/linear-tui / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。