对象组合:存储引用与引用的ID



返回关于Rust中基本设计决策的另一个noob问题。

我在写一个简单的小游戏。我在数据结构中有一个游戏对象池,由它们的"id"键控。我的问题是如何处理与池中对象有关系的其他结构(寿命比池中的结构短)。

一开始我做了以下事情:

struct Foo<'a> {
  game_obj: &'a GameObject
  // etc.
}

但是,当我试图(可变地)引用与现有Foo相同范围内的GameObject时,借用检查器遇到了一堆问题。

所以现在我正在考虑这样的东西:

struct Foo {
  game_obj_id: uint,
  // etc.
}

这可能还有其他问题,但它确实解决了Foo"垄断"引用其相关GameObject的能力的直接问题。

对此有哪些常用方法?

您可以将Rc<RefCell<GameObject>>存储在struct中(除非GameObject是一个特性,在这种情况下,只有实现动态大小类型(DST)才能工作)。

RefCell<T>是一种类型,它包含T和一个标志,该标志指示该值是否已被可变地借用、是否已被免疫地借用或是否未被借用。RefCell基本上是在运行时而不是在编译时移动借用检查;如果违反了借用规则(如果已经可变或不可变地借用,则不能进行可变借用;如果已经可变地借用则不能进行不可变借用),则任务将失败。请注意,可以同时存在多个不可变的借用。

Rc<T>是一种类型,它包含指向T的指针和引用计数(实际上是两个:强引用计数和弱引用计数)。您可以.clone()Rc来增加引用计数,而无需克隆基础对象。当Rc被丢弃时,参考计数被递减。当引用计数降至零时,将删除引用并回收内存。注意,Rc已经动态地分配了内存;不需要使用诸如Rc<Box<Thing>>之类的构造(除非您知道自己在做什么)。

还有Weak<T>,它可以代替Rc用于不需要保持对象活动的引用。

最新更新