rust - 借用 GameMaster (self) 到 GameState
问题描述
我对 Rust 还很陌生,我一直在尝试使用ggez 制作一个简单的游戏。
现在,通常在 C++ 或 C# 中,我会围绕一个“主”类的实例来构建我的游戏,该实例负责设置、帧限制、窗口创建、事件处理等,以及由主类持有的“状态”类. 在创建状态类(类似于game_master*
)时,我会传递一个指向主类的指针,以便状态类可以访问主类的资源。
在 Rust 中我不能通过 a&mut self
因为状态可能比引用更长寿。
pub fn new(_ctx: &mut Context) -> GameMaster {
let game = GameMaster {
state: None,
pending_state: None
};
game.state = Some(Box::new(TestState::new_with_master(&mut game))) <----- NOPE
game
}
我认为这可以通过生命周期来解决,但我还没有找到一种方法让生命周期与特征一起工作。在每个函数调用中将 master 作为引用传递也不起作用,因为一次只能保存一个可变引用。
fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
if self.state.is_some() {
(*self.state.as_mut().unwrap()).update(ctx, &mut self) <----- NOPE
}
else {
Ok(())
}
}
在 Rust 中没有好的方法可以做到这一点吗?
解决方案
不久前我有一个类似的问题,但我认为唯一的选择是:
Rc<RefCell<>>
到处使用。Weak
如果您需要对这些对象进行垃圾收集,请记住还要使用或添加特殊的销毁方法,因为它们相互引用。使用原始指针和不安全的代码。问题在于,如果使用不安全的尊重,
RefCell
除了生命周期检查之外,您还会丢失可变性检查(确保一次只存在一个可变引用)。
推荐阅读
- c++ - GTest 的 EXPECT_EQ 给出了未定义的错误引用
- sql - SQL - 在 WHERE 子句中使用计算日期
- .net-core - 当有未确认的未确认消息时,RabbitMQ 消费者变慢
- python - Keras 自定义回调以保存历史字典和回调顺序
- c# - c# Linux/Raspbian 中的 Mono App 在提供套接字时无法从串行端口读取(可以写入 / 但串行输入缓冲区报告 0 字节)
- java - 不同的 HashMap 大小 (Java)
- bootstrap-4 - Angular 6 + Bootstrap 4 添加带有@HostBinding 的“show”类
- admob - 颤振:firebase_admob 广告未显示
- mysql - docker-compose / mysql:如何正确指定卷以使用现有数据库
- javascript - Typescript - Setter/Getter 的优点?