dyn互換のトレイト

// 著作権 2025 Google LLC
// SPDX-License-Identifier: Apache-2.0

pub trait Trait {
    // dyn互換
    fn takes_self(&self);

    // dyn互換だが、dyn の場合はこのメソッドを使えない
    fn takes_self_and_param<T>(&self, input: &T);

    // dyn互換ではなくなる
    const ASSOC_CONST: i32;

    // dyn互換ではなくなる
    fn clone(&self) -> Self;
}
  • すべてのトレイトがトレイトオブジェクトとして呼び出せるわけではありません。呼び出せるトレイトは dyn互換 トレイトと呼ばれます。

  • 以前はこれを object safe traits または object safety と呼んでいました。

  • 動的ディスパッチでは、コンパイル時の型情報の多くが実行時の vtable 情報へと移されます。

    ある概念が、vtable に意味のある形で格納できるものと両立しない場合、 そのトレイトは dyn互換ではなくなるか、あるいはそのメソッドは dyn コンテキストで使えないように除外されます。

  • あるトレイトが dyn互換であるのは、すべてのスーパートレイトが dyn互換であり、 関連定数や関連型を持たず、ジェネリクスに依存するメソッドを持たない場合です。

  • dyn非互換なトレイトに最もよく遭遇するのは、それらが関連型/関連定数を 持っている場合や、Self を返す場合です(つまり Clone トレイトは dyn互換ではありません)。

    これは、関連するデータを vtable に格納する必要があり、そのぶん 追加のメモリを消費するためです。

    clone のようなメソッドでは、出力型が self の具体的な型に依存するため、 これにより dyn互換ではなくなります。

参照:

  • https://doc.rust-lang.org/1.91.1/reference/items/traits.html#r-items.traits.dyn-compatible