🧩

トレイトとジェネリクス — 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

参考資料