2017-03-05 1 views
2

は、これら二つの特性を考慮してください。なぜ型パラメーターを持つ形質にブランケットインプを追加できないのですか?

pub trait Foo { 
    fn new(arg: u32) -> Self; 
} 

pub trait Bar<P>: Foo { 
    fn with_parameter(arg: u32, parameter: P) -> Self; 
} 

私はブランケットIMPL追加したい:

impl<T: Bar<P>, P: Default> Foo for T { 
    fn new(arg: u32) -> Self { 
     Self::with_parameter(arg, P::default()) 
    } 
} 

をしかし、私は、コンパイラのエラーを取得:

error[E0207]: the type parameter `P` is not constrained by the impl trait, self type, or predicates 

私はこれを取得だと思うが私は特性の一貫性のルールに違反しているので、エラーが発生しますが、これがどのようなルールを破るかは正確に分かりません。なぜこのパターンは許されないのですか?そして、もっと重要なのは、エラーを出さずに私が望むものを達成できるかどうかです。

答えて

4

問題は、1つのタイプがPの複数の値に対してBar<P>を実装できることです。 Bar<i32>Bar<String>を実装した構造体Bazがある場合は、PにはFoo::newを使用する必要がありますか?

唯一の解決策は、1つのタイプがBarを2回以上実装できないようにすることです(それがあなたが望むものでない場合は、デザインに欠陥があります)。これを行うには、タイプパラメータPを関連タイプに置き換える必要があります。

pub trait Bar: Foo { 
    type Parameter; 

    fn with_parameter(arg: u32, parameter: Self::Parameter) -> Self; 
} 

impl<T> Foo for T 
    where T: Bar, T::Parameter: Default 
{ 
    fn new(arg: u32) -> Self { 
     Self::with_parameter(arg, T::Parameter::default()) 
    } 
} 

Barの実装は次のようになります。

struct Baz; 

impl Bar for Baz { 
    type Parameter = i32; 

    fn with_parameter(arg: u32, parameter: Self::Parameter) -> Self { 
     unimplemented!() 
    } 
} 
関連する問題