gpt4 book ai didi

rust - 如何创建异构对象集合?

转载 作者:行者123 更新时间:2023-12-03 11:48:32 25 4
gpt4 key购买 nike

我想在Vec中使用特征对象。在C++中,我可以创建一个基类Thing,从该基类派生Monster1Monster2。然后,我可以创建一个std::vector<Thing*>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,
}

我用 ThingTraitget_thing_record()attack()等方法定义了 make_noise(),并为 Monster1Monster2实现了它们。

最佳答案

特质对象
实现对象的异构集合(在这种情况下是向量)的最可扩展的方法就是您拥有的:

Vec<Box<dyn ThingTrait + 'static>>
尽管有时您可能想要的生命周期不是 'static,所以您将需要类似以下内容:
Vec<Box<dyn ThingTrait + 'a>>
您也可以具有对特征的引用的集合,而不是盒装特征:
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)];
}
Box<dyn SomeTrait>Rc<dyn SomeTrait>&dyn SomeTrait等都是特征对象。这些允许在无限数量的类型上实现特征,但是权衡是它需要一定数量的间接和动态分配。
也可以看看:
  • What makes something a "trait object"?
  • What does "dyn" mean in a type?

  • 枚举
    如评论中所述,如果您有固定数量的已知替代方案,那么开放程度较小的解决方案是使用枚举。这不需要对值进行 Box编码,但是它仍然会有少量的动态调度来确定在运行时存在哪种具体的枚举变量:
    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)];
    }
    也可以看看:
  • Why does an enum require extra memory size?
  • 关于rust - 如何创建异构对象集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62262837/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com