如何初始化相互引用的struct字段

mau*_*aun 23 rust

我目前想要使用GamerIterator 为活塞游戏定义一个结构:

pub struct MyGame<'a> {
    game_window: GameWindowGLFW,
    game_iter: GameIterator<'a, GameWindowGLFW>,
    //...
}
Run Code Online (Sandbox Code Playgroud)

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
    //...
}
Run Code Online (Sandbox Code Playgroud)

我认为我可以通过使用Option<GameIterator<...>>和init()方法解决初始化问题,但我想避免这种情况,因为我可以保证game_iternew()完成后存在.

写这个的惯用方法是什么?

Fra*_*gné 12

不仅有与初始化的问题,也可能有问题与破坏,如果GameIterator实现Drop:编译器必须知道它需要进行破坏game_iter之前game_window,否则game_window就必须参照的破坏GameWindowGLFW运行它,而drop()方法.

没有办法将结构本身的生命周期作为生命周期参数传递.你唯一能做的就是game_window从中删除字段MyGame并将GameWindowGLFW实例传递给MyGame初始化程序.如果要封装它以便用户不需要创建GameWindowGLFW,则可以编写一个在堆栈上创建a GameWindowGLFW和a 的方法,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 */
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,我明白了原因,但它不起作用仍然很奇怪......也想不出编译器可以轻松验证的安全和通用解决方案,这一切都取决于依赖项和初始化/销毁顺序。 (3认同)