トレイトが dyn
互換かどうかをマークする方法について。
トレイトが dyn
互換かどうかは重要である。しかし、Rust の文法はこれをトレイト全体の内容から判断する。トレイトに何かマークをつけるようなスタイルではない。そのため、コードリーディング時に瞬間的な判断ができない。また、メソッドの追加や削除で思いがけず dyn
互換かどうかまでもを変更してしまうかもしれない。
このような心配は dyn
互換かどうかを明示的にマークできれば不要になる。
『dyn 型の実装』が dyn
互換の型にしか使えないのを利用する。
pub trait MyTrait {
fn some_method(&self);
}
impl dyn MyTrait {}
dyn
非互換のマーカートレイトを基底にする。そして、マーカートレイトに dyn
非互換にするダミーメソッドを入れておく。このダミーメソッドは呼ばれても問題ないが、絶対に呼ばれたくないなら『Voldemort パターン - トレイトメソッドの仮想的な非公開化』も使える。
pub trait MyTrait: NotDyn {
fn some_method(&self);
}
pub trait NotDyn {
#[doc(hidden)]
fn __do_not_call() {}
}
impl<T: ?Sized> NotDyn for T {}
ここで紹介した方法をトレイトへの属性マクロで実現するクレート。
トレイトに #[dyn_compatible(true)]
のように指定するだけで機能する。