Rust 如何创建异构对象集合?

Rust 如何创建异构对象集合?,rust,Rust,我想在Vec中使用trait对象。在C++中,我可以生成一个基类 Test< ,从中派生出代码> MunStest代码>。然后我可以创建一个std::vectorThing对象必须存储一些数据,例如x:int,y:int,但派生类需要添加更多数据 目前我有一些 struct Level { // some stuff here pub things: Vec<Box<ThingTrait + 'static>>, } struct ThingRecord

我想在
Vec
中使用trait对象。在C++中,我可以生成一个基类<代码> Test< <代码>,从中派生出代码> MunStest<和 MunStult2>代码>。然后我可以创建一个
std::vector
Thing
对象必须存储一些数据,例如
x:int,y:int
,但派生类需要添加更多数据

目前我有一些

struct Level {
    // some stuff here
    pub things: Vec<Box<ThingTrait + 'static>>,
}

struct ThingRecord {
    x: i32,
    y: i32,
}

struct Monster1 {
    thing_record: ThingRecord,
    num_arrows: i32,
}

struct Monster2 {
    thing_record: ThingRecord,
    num_fireballs: i32,
}
结构级{ //这里有些东西 酒吧用品:VecTrait对象 实现异构对象集合(在本例中为向量)的最可扩展方式正是您所拥有的:

Vec<Box<dyn ThingTrait + 'static>>
您还可以有一组对特征的引用,而不是装箱的特征:

Vec<&dyn ThingTrait>
另见:


如果你的怪物大多是事先知道的(即你没有创建一个允许所有人创建新怪物的游戏引擎),你也可以使用enumSee(顺便说一句,如果交叉发布问题,通常礼貌的做法是至少在它们之间建立链接,以便感兴趣的人不会错过讨论。)好的,我在使用特征和返回共享数据的方法之间很难…或者只是用枚举来表示所有的东西。我认为前者是两个邪恶的较小。如果继承将被添加到语言中,它会是什么样子?除此之外,我几乎没有什么东西会错过C++。呼吸新鲜空气。锈博客湾rs this:--一个优秀的读取IMHO。请注意,枚举具有其最大选项的大小。如果您的怪物也有一个大数组的选项,那么向量中怪物的每个实例都会有一个大数组的内存占用。
Vec<&dyn ThingTrait>
trait ThingTrait {
    fn attack(&self);
}

impl ThingTrait for Monster1 {
    fn attack(&self) {
        println!("monster 1 attacks")
    }
}

impl ThingTrait for Monster2 {
    fn attack(&self) {
        println!("monster 2 attacks")
    }
}

fn main() {
    let m1 = Monster1 {
        thing_record: ThingRecord { x: 42, y: 32 },
        num_arrows: 2,
    };

    let m2 = Monster2 {
        thing_record: ThingRecord { x: 42, y: 32 },
        num_fireballs: 65,
    };

    let things: Vec<Box<dyn ThingTrait>> = vec![Box::new(m1), Box::new(m2)];
}
enum Monster {
    One(Monster1),
    Two(Monster2),
}

impl Monster {
    fn attack(&self) {
        match *self {
            Monster::One(_) => println!("monster 1 attacks"),
            Monster::Two(_) => println!("monster 2 attacks"),
        }
    }
}

fn main() {
    let m1 = Monster1 {
        thing_record: ThingRecord { x: 42, y: 32 },
        num_arrows: 2,
    };

    let m2 = Monster2 {
        thing_record: ThingRecord { x: 42, y: 32 },
        num_fireballs: 65,
    };

    let things = vec![Monster::One(m1), Monster::Two(m2)];
}