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

时间:2014-08-12 16:36:17

标签: rust

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

pub struct MyGame<'a> {
    game_window: GameWindowGLFW,
    game_iter: GameIterator<'a, GameWindowGLFW>,
    //...
}

GameIteratorGameWindow及其生命周期中是通用的。我想告诉编译器它与字段“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}之后完成。

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

1 个答案:

答案 0 :(得分:11)

初始化不仅存在问题,如果GameIterator已实现Drop,也可能存在破坏问题:编译器必须知道它需要先破坏game_iter game_window,否则game_window会在运行其GameWindowGLFW方法时引用已销毁的drop()

没有办法将结构本身的生命周期作为生命周期参数传递。您唯一能做的就是从game_window中删除MyGame字段,然后将GameWindowGLFW个实例传递给MyGame的初始化程序。如果要封装它以便用户不需要创建GameWindowGLFW,您可以编写一个方法,在堆栈上创建GameWindowGLFWMyGame并调用闭包只接受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 */
    });
}