2016-09-01 2 views
0

특정 빌더 패턴을 시험 중이다. 제발 신경 쓰지 마세요 - 시험입니다.특성을 구현하여 리턴하는 유형 일치

set_shape을 산출하는 Renderer 유형이 있습니다. 호출에 제공된 인수 유형은 빈 특성 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!"), 
     } 
    } 
} 

이렇게하고 싶습니다. PSEUDO :

대신 match를 사용
match shape { 
    Rectangle => return RectangleShapeBuilder, 
    Circle => return CircleShapeBuilder, 
    _ => panic!("WTF!"), 
} 

답변

5

, 당신은 특정 구현에 적합한 빌더를 반환하여 IsRenderable 특성에 메소드를 추가해야합니다. 관련 유형과 팁을위한

#[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

감사 :

#[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 권투 방지하기 위해 관련 유형을 사용할 수 있습니다! – xetra11

+0

또한 두 번째 코드 스 니펫에서'set_shape'의 리턴 타입은 이름 충돌을 피하기 위해' :: Builder'이어야한다고 생각하십니까? –

+2

@LukasKalbertodt : 모든 컴파일러가'T'에 대해 알고 있기 때문에'T :: Builder'는 "IsRenderable"형식의 관련 유형'Builder '를 정적으로 해결하기 때문에 이름 충돌이 문제라고 생각하지 않습니다. 'IsRenderable'을 구현한다는 것입니다. Rust는 C++ 템플릿처럼 작동하지 않습니다. 종속 템플릿 유형은 템플릿 인스턴스화시에만 해결됩니다. 또 다른 특성 경계를 추가하면 모호성이 발생할 수 있지만 헤비급 구문으로 곧바로 이동하는 대신 모호성이 발생하면 해결할 수 있습니다. –

관련 문제