如何在Rust中实现抽象工厂?

就像是:

trait Thingy {
    fn hallo(&self);
}

trait Factory {
    fn make(&self) -> Thingy;
}
//------------------------------
struct AThingy {}

impl Thingy for AThingy {
    fn hallo(&self) {
        println!("i'm A thingy");
    }
}

struct AFactory {}

impl Factory for AFactory {
    fn make(&self) -> AThingy {
        AThingy{}
    }
}

//------------------------------
struct BThingy {}

impl Thingy for BThingy {
    fn hallo(&self) {
        println!("i'm B thingy");
    }
}

struct BFactory {}

impl Factory for BFactory {
    fn make(&self) -> BThingy {
        BThingy{}
    }
}

//------------------------------
#[test]
fn test_factory() {
    let aFactory:Factory = AFactory{};
    let bFactory:Factory = BFactory{};
    
    aFactory.make().hallo();
    bFactory.make().hallo();
}

试图在不同的地方附加 Sized 但都失败了。

回答

您可以使用关联类型Factory可以有一个关联的类型,称为Output. 您可以添加需要Output实现的边界Thingy

trait Factory {
    type Output: Thingy;
    
    fn make(&self) -> Self::Output;
}

现在AFactoryOutput将是AThingy

impl Factory for AFactory {
    type Output = AThingy;
    
    fn make(&self) -> AThingy {
        AThingy {}
    }
}

BFactoryOutput将是BThingy

impl Factory for BFactory {
    type Output = BThingy;
    
    fn make(&self) -> BThingy {
        BThingy {}
    }
}

正如@PeterHall 提到的,您无法在 Rust 中处理未定义大小的类型,因此要存储 aFactory您需要使用拥有的指针,例如Box<dyn Factory>

#[test]
fn test_factory() {
    let aFactory: Box<dyn Factory> = Box::new(AFactory {});
    let bFactory: Box<dyn Factory> = Box::new(BFactory {});

    aFactory.make().hallo();
    bFactory.make().hallo();
}

但是,因为Factory有关联类型,所以Output在将其放入特征对象时还必须指定:

#[test]
fn test_factory() {
    let aFactory: Box<dyn Factory<Output = AThingy>> = AFactory {};
    let bFactory: Box<dyn Factory<Output = BThingy>> = BFactory {};

    aFactory.make().hallo();
    bFactory.make().hallo();
}


以上是如何在Rust中实现抽象工厂?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>