如何创建异构的对象集合?我想在一个中使用特征对象Vec。在C ++中我可以使一个基类Thing从中导出Monster1和Monster2。然后我可以创建一个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,}我定义了一个ThingTrait与方法get_thing_record(),attack(),make_noise()等,并实现它们的Monster1和Monster2。
1 回答
千巷猫影
TA贡献1829条经验 获得超7个赞
特质对象
实现对象的异构集合(在本例中为向量)的最可扩展方式正是您所拥有的:
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<SomeTrait>
,Rc<SomeTrait>
,&SomeTrait
等都是性状的对象。这些允许在无数种类型上实现特征,但权衡是需要一定量的间接和动态调度。
枚举
正如评论中所提到的,如果您有固定数量的已知替代方案,那么开放性较低的解决方案就是使用枚举。这不需要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)];}
添加回答
举报
0/150
提交
取消