2015-05-25 35 views
6

bir parametreli özellik için bir özelliği nasıl uygulanır, gibi bir şey kullanırken:Bir tasarım sorunu var

trait MyTrait<K: OtherTrait> { ... } 

impl<K: OtherTrait, M: MyTrait<K>> AnyTrait for M { ... } 

nedeniyle E207 hatası ("K kısıtlı değildir tipi parametresine bu özellik için özellik uygulayamaz impl özelliği, kendi kendine tür veya yüklem "" ile. hiçbir şekilde bulma

Bu hatanın kurtulmak için, ben this not-so-good-looking workaround (hiçbir gerçek değeri ile ayrıntılı ve yapı) uygulanır:

bence
use std::fmt; 
use std::marker::PhantomData; 

pub trait MyTrait<K: fmt::Display> { 
    fn get_some_k(&self) -> Option<K>; 
} 

/* // This is my target impl but results in E207 due to K not constrained 
impl<K: fmt::Display, S: MyTrait<K>> fmt::Display for S { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "{}", self.get_some_k().unwrap()) 
    } 
} */ 
pub struct Ugly<'a, K: fmt::Display, S: 'a + MyTrait<K>>(&'a S, PhantomData<K>); 
impl<'a, K: fmt::Display, S: MyTrait<K>> fmt::Display for Ugly<'a, K, S> { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "{}", self.0.get_some_k().unwrap()) 
    } 
} 

fn main() { } 

bu tür bir özellik uygulamak için bazı güzel bir yol olmalıdır parametreli özellik.

std'de iyi bir örnek bulamadım (örneğin Iterator gibi ilişkili türdeki Display uygulamalarında)? (Yalnızca türü başına bir K için MyTrait uygulamak anlamına gelir)

+0

Sadece aynı konuya koştuğumu belirtmek isterdim, ancak 'Mytrait' kullanıcılara açık bir özellik olan 'Ugly' battaniyesi impelleme lüksüne sahip değilim. ve “Çirkin” kullanmalarını gerektiren, gereksiz karmaşıklık ekleyerek API'yi iyice mahvediyor. – mindTree

+0

Olası bir kopyası [Bir Özel Özellik İçin Battaniye Özellik Uygulamalarının Sağlanması] (http://stackoverflow.com/questions/32430659/providing-blanket-trait-implementations-for-a-custom-trait) – wimh

cevap

2

Here’s an implementation using associated types: Böyle açıklık Ancak

use std::fmt; 

pub trait MyTrait { 
    type K: fmt::Display; 
    fn get_some_k(&self) -> Option<Self::K>; 
} 

impl<S: MyTrait> fmt::Display for S { 
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 
     write!(f, "{}", self.get_some_k().unwrap()) 
    } 
} 

fn main() { } 

, bunu çünkü bu yaklaşım, ya işe yaramaz ortaya çıkıyor Kendi Display uygulamasına sahip olabilecek MyTrait uygulayan tüm türler için Display uygulanıyor. Bu yasak ve böylece E0210 olsun: içinde

error: type parameter S must be used as the type parameter for some local type (e.g. MyStruct<T>); only traits defined in the current crate can be implemented for a type parameter [E0210]

onu tamamlayan bir şeye benzeri senin Ugly did-böyle bir şekilde yürütülebilmesi için tek yol. Veya bir başkasının (örneğin Display gibi) kendi sandığınızda bir özellik uygulayın.

+0

Teşekkürler, ilişkili ile ilgili düşündüm türü, ancak ben tür başına birden fazla uygulamaya ihtiyaç duyduğum durumda, aksi takdirde iş (benim kullanım durumum 'Display' değil) yapmış olurdu. – cheme