[英]If or How to use references and lifetimes
我正在通过实现一个简单的游戏来试验 rust,并很快遇到一种情况,我发现很难决定什么是更好的方法,我认为这与 Rust 中关于引用和生命周期的更广泛问题有关,希望有人有更好的经验。
假设我有一个代表Game
世界的游戏,而GameObject
是游戏中所有项目的特征。 和一个GameState
来跟踪每次更新的 object 次碰撞,Collision 需要保存对其他GameObject
的引用,以便判断哪些发生碰撞,为此我需要为Collision
添加生命周期,然后将生命周期添加到GameState
如果我希望游戏 object 保留 state,然后添加到Game
,或者我可以为每个更新滴答复制游戏状态。
trait GameObject {
fn draw(&self, renderer: &Renderer);
fn update(&mut self, state: &GameState, delta: f64);
}
struct Collision<'a> {
obj1: &'a Box<dyn GameObject>,
obj2: &'a Box<dyn GameObject>
}
struct GameState<'a> {
// other states...
collisions: Vec<Collision<'a>>,
}
struct Game {
items: Box<dyn GameObject>,
}
impl Game {
fn draw(&self, renderer: &Renderer){
for item in &self.items {
item.draw(render);
}
}
fn update(&mut self, delta: f64){
// create a state everytime? or hold a reference to it?
for item in &self.items {
item.update(delta);
}
}
}
所以这就是我 100% 确定什么是最好的方法,或者一般来说,一旦我们给 object 一个生命周期,那么任何其他 object 持有这个 object 将需要生命周期类型,而不是我们应该重新组织代码结构以避免一生? 谢谢。
我的建议是在临时结构中使用生命周期,但避免将它们用于您想要保留的结构。 所以如果你为每一帧创建一个 GameState,添加到它,使用它并销毁它,那没关系。 但是如果你想让它在很多帧中保持活动状态,那么这些引用就会成为一个问题,因为你将一直保持你的对象被借用。
如果您的对象之间有复杂的引用,有几种不需要生命周期和持久借用的解决方案:
Rc<dyn GameObject>
而不是Box
并将指针的Weak
版本存储在主容器以外的任何地方。SlotMap
中,并使用键来引用对象。Vec
中并使用索引来引用对象。 它就像SlotMap
但更简单。 对于更简单的情况仍然有用,例如您的对象只创建一次,然后从未添加或删除。Bevy
在上面的评论中建议的 Bevy。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.