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