匹配实现特征的类型,从而返回它

时间:2016-09-01 04:20:48

标签: pattern-matching rust traits

我正在尝试一些特定的构建器模式。请不要介意这里的设计 - 这是一个试用。

我有一个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!"),
}

1 个答案:

答案 0 :(得分: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()
}