2017-03-05 73 views
2

考慮以下兩個特點:爲什麼我不能在類型參數的特徵上添加毯子impl?

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

問題是單個類型可以實現Bar<P>多個值P。如果您有一個結構Baz,實施了Bar<i32>Bar<String>,哪種類型的Foo::new應用於P

唯一的解決方案是確保一個類型不能多次執行Bar(如果這不是你想要的,那麼你的設計就有缺陷!)。爲此,我們必須用相關類型替換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!() 
    } 
} 
相關問題