🧩
トレイトとジェネリクス — Rustの多態性
インターフェース+ジェネリクスが合わさったRustの抽象化ツール
トレイトは「この型はこの動作ができる」を定義する。Javaのinterfaceに似ているが、既存の型に後からtraitをimplできる点が異なる。
trait Summary {
fn summarize(&self) -> String;
}
ジェネリック関数でwhere T: Summaryのようなtrait boundを使うと、コンパイラが具体型ごとに関数を個別生成(monomorphization)するため、ランタイムのvtableコストがない。
dyn Traitを使うとランタイム多態性(動的ディスパッチ)も可能。この場合vtable経由の間接呼び出しが発生する。
キーポイント
1
traitで共通動作(メソッドシグニチャ)を定義
2
impl Trait for Typeで具体型に実装
3
ジェネリクス+trait boundでコンパイル時多態性(静的ディスパッチ)
4
dyn Traitでランタイム多態性が必要な時に動的ディスパッチ
メリット
- ✓ ゼロコスト抽象化 — ジェネリクスはmonomorphizationでインライン化
- ✓ 既存型への後付け実装可能(orphan rule範囲内)
デメリット
- ✗ monomorphizationでバイナリサイズが大きくなる場合がある
- ✗ トレイト制約が複雑になるとwhere節が長くなる
ユースケース
シリアライゼーション — serdeのSerialize/Deserializeトレイト
非同期ランタイム — Futureトレイトベースのasync/await