ジェネリック関数パラメータ vs dyn Trait

多相的な関数を書くには 2 つの方法がありますが、それらはどのように比較できるでしょうか?

// Copyright 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

fn print_display<T: std::fmt::Display>(t: &T) {
    println!("{}", t);
}

fn print_display_dyn(t: &dyn std::fmt::Display) {
    println!("{}", t);
}

fn main() {
    let int = 42i32;
    // i32 入力用の固有の関数に単相化される。
    print_display(&int);
    // 各型につき 1 つ
    print_display_dyn(&int);
}
  • ジェネリクスまたはトレイトオブジェクトを使って、多相的な関数を書けます。

  • ジェネリックパラメータを持つ関数を書く場合、パラメータに代入される型ごとに、その関数の新しいバージョンが生成されます。

    これは単相化で見たとおりです。バイナリサイズと引き換えに、より高い最適化の余地が得られます。

  • トレイトオブジェクトを受け取る関数を書く場合、その関数のバージョンは最終的なバイナリには 1 つしか存在しません(インライン化は除きます)。

  • ジェネリックパラメータは、バイナリサイズを除けばゼロコストです。型は均質でなければなりません(T のすべてのインスタンスは同じ型でしかありえません)。