2016-09-01 104 views
0

我正在嘗試一些特定的生成器模式。請不要介意這裏的設計 - 這是一個試用。匹配實現特質的類型,因此返回它

我有一個Renderer類型,它產生一個方法set_shape。給這個調用的參數類型應該實現空的特徵IsRenderable。 方法的登錄名應該在結構類型RectangleCircle之間有所不同,它們都實現了IsRenderable特徵。不要擔心返回類型。

#[derive(Clone, Copy)] 
pub struct Rectangle { 
    pub origin: Point, 
    pub height: usize, 
    pub width: usize, 
} 

trait IsRenderable {} 

impl IsRenderBuilder for Rectangle {} 

impl<'a> Renderer<'a> { 
    // logic that needs lifetime 'a 
    pub fn set_shape<T: IsRenderable>(shape: T) -> Box<IsRenderBuilder> { 
     match shape { 
      _ => panic!("WTF!"), 
     } 
    } 
} 

我想做這樣的事情。

match shape { 
    Rectangle => return RectangleShapeBuilder, 
    Circle => return CircleShapeBuilder, 
    _ => panic!("WTF!"), 
} 

回答

5

而不是使用match的,你應該在你的IsRenderable特點,用於返回特定的實現者適當的參數中加入的方法。

#[derive(Clone, Copy)] 
pub struct Rectangle; 

pub trait IsRenderable { 
    fn new_builder(&self) -> Box<IsRenderBuilder>; 
} 

impl IsRenderable for Rectangle { 
    fn new_builder(&self) -> Box<IsRenderBuilder> { 
     Box::new(RectangleShapeBuilder) 
    } 
} 

struct RectangleShapeBuilder; 

pub trait IsRenderBuilder {} 

impl IsRenderBuilder for RectangleShapeBuilder {} 

pub fn set_shape<T: IsRenderable>(shape: T) -> Box<IsRenderBuilder> { 
    shape.new_builder() 
} 

你甚至可能使用相應的類型,以避免拳擊IsRenderBuilder

#[derive(Clone, Copy)] 
pub struct Rectangle; 

pub trait IsRenderable { 
    type Builder: IsRenderBuilder; 

    fn new_builder(&self) -> Self::Builder; 
} 

impl IsRenderable for Rectangle { 
    type Builder = RectangleShapeBuilder; 

    fn new_builder(&self) -> Self::Builder { 
     RectangleShapeBuilder 
    } 
} 

pub struct RectangleShapeBuilder; 

pub trait IsRenderBuilder {} 

impl IsRenderBuilder for RectangleShapeBuilder {} 

pub fn set_shape<T: IsRenderable>(shape: T) -> T::Builder { 
    shape.new_builder() 
} 
+0

感謝您與相關類型的提示! – xetra11

+0

另外:我認爲第二個代碼片段中'set_shape'的返回類型應該是' :: Builder',以避免可能的名稱衝突? –

+2

@LukasKalbertodt:我不認爲名稱衝突是一個問題,因爲'T :: Builder'靜態地解析爲意味着「IsRenderable'特徵中的相關類型'Builder'」,因爲所有編譯器都知道'T'它實現了'IsRenderable'。 Rust不像C++模板那樣工作,其中依賴類型僅在模板實例化時解析。添加另一個特徵綁定可能會引起歧義,但是當歧義被引發時可以解決這個問題,而不是直接使用重量級語法。 –

相關問題