就像是:
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 但都失败了。
什么时候Thingy是一个特质,这个:
fn make(&self) -> Thingy;
相当于:
fn make(&self) -> dyn Thingy;
也就是说,一个未调整大小的裸特征对象。你不能像 Rust 那样处理未定义大小的类型;特征对象需要位于某种类型的指针后面。鉴于该函数创建对象,它不能是 a &dyn Thingy,因此您需要一个拥有的指针,例如Box<dyn Thingy>。
所以你的Factory特质看起来像这样:
trait Factory {
    fn make(&self) -> Box<dyn Thingy>;
}
实现如下所示:
impl Factory for AFactory {
    fn make(&self) -> Box<dyn Thingy> {
        Box::from(AThingy{})
    }
}
鉴于您的问题,我猜您正在尝试应用您习惯的面向对象语言(例如 Java)的模式。这些模式违背了 Rust 中常用的习惯用法,并迫使您对数据进行装箱,否则这些数据可能不需要装箱。在 Java 中,几乎所有通用的东西都被装箱了,并且你为此付出了代价。
您可以使用关联类型。Factory可以有一个关联的类型,称为Output. 您可以添加需要Output实现的边界Thingy:
trait Factory {
    type Output: Thingy;
    
    fn make(&self) -> Self::Output;
}
现在AFactory的Output将是AThingy:
impl Factory for AFactory {
    type Output = AThingy;
    
    fn make(&self) -> AThingy {
        AThingy {}
    }
}
和BFactory的Output将是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();
}