我目前想要使用GamerIterator为Piston游戏定义一个结构:
pub struct MyGame<'a> {
game_window: GameWindowGLFW,
game_iter: GameIterator<'a, GameWindowGLFW>,
//...
}
GameIterator
在GameWindow
及其生命周期中是通用的。我想告诉编译器它与字段“game_window”/“整个结构”具有相同的生命周期,并省略了结构的生命周期。
我在初始化时也遇到了困难:
MyGame {
game_window: GameWindowGLFW::new(GameWindowSettings {/*...*/},
game_iter: GameIterator::new(&mut game_window, &game_iter_settings), // game_window cannot be used here
//...
}
我认为我可以通过使用Option<GameIterator<...>>
和init()方法解决初始化问题,但我想避免这种情况,因为我可以保证game_iter
出现在{{1}之后完成。
写这个的惯用方法是什么?
答案 0 :(得分:11)
初始化不仅存在问题,如果GameIterator
已实现Drop
,也可能存在破坏问题:编译器必须知道它需要先破坏game_iter
game_window
,否则game_window
会在运行其GameWindowGLFW
方法时引用已销毁的drop()
。
没有办法将结构本身的生命周期作为生命周期参数传递。您唯一能做的就是从game_window
中删除MyGame
字段,然后将GameWindowGLFW
个实例传递给MyGame
的初始化程序。如果要封装它以便用户不需要创建GameWindowGLFW
,您可以编写一个方法,在堆栈上创建GameWindowGLFW
和MyGame
并调用闭包只接受MyGame
参数。
pub struct MyGame<'a> {
game_iter: GameIterator<'a, GameWindowGLFW>,
//...
}
impl<'a> MyGame<'a> {
fn new(game_window: &'a mut GameWindowGLFW) -> MyGame<'a> {
MyGame {
game_iter: GameIterator { game_window: game_window },
}
}
}
fn start_game(callback: |game: &mut MyGame|) {
let mut game_window = GameWindowGLFW;
let mut game = MyGame::new(&mut game_window);
callback(&mut game);
}
fn main() {
start_game(|game| {
/* use game here */
});
}