2017-01-23 1 views
5

fooは、形質を実装するタイプのインスタンスをとるAです。私はいつも、静的ディスパッチを持つためにジェネリックを使用することを好む:動的および静的なディスパッチを持つ特性作成者のための機能を実装する

trait A {} 

fn foo<T: A>(t: T) {} 

しかし、このアプローチは、いくつかの硬直を紹介し、私はここのような形質オブジェクトを渡すことはできません。

trait A {} 

fn foo(t: &A) {} 

事は、ときどき私はそのタイプを知っていることがあります。 traitオブジェクトの動的ディスパッチとコンパイル時の既知の型の静的ディスパッチの両方を実装する方法はありますか?

答えて

6

これは確かに可能です。 1つのオプションは、明示的に参照型のためAを実装することです:

impl<'a, T: A + ?Sized> A for &'a T {} 

引数は、まだAの知られている実装のための静的な派遣をしながら、形質オブジェクトT = &Aとなります。次のコードは、今コンパイルする必要があります

fn foo<T: A>(a: T) {} 

struct MyA; 
impl A for MyA {} 

fn main() { 
    foo(MyA{}); 
    foo(&MyA{}); 
    foo(&MyA{} as &A); 
} 

あなたはいつも借り引数を渡すために喜んでいる場合

が、あなたはまた、代わりにこれを行うことができます:

fn foo<T: A + ?Sized>(a: &T) {} 

引数は、形質オブジェクトT = Aとなります。

+0

あなたの 'fn foo'を完全に理解しているかどうかはわかりません。 'Sized'には常に暗黙的な境界がありますか? – torkleyy

+1

@torkleyy関数の引数は、yesです。どちらの場合でも、私たちが提供しているものは実際には常にサイズが決められているので、これは大丈夫です。 2番目の関数は、Tがそうでなくても、サイズの '&T'をとります。 –

関連する問題