【问题标题】:How to initialize struct fields which reference each other如何初始化相互引用的结构字段
【发布时间】:2015-11-06 10:31:51
【问题描述】:

我目前想使用 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&lt;GameIterator&lt;...&gt;&gt; 和 init() 方法来解决初始化问题,但我想避免这种情况,因为我可以保证 game_iternew() 完成后存在。

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

【问题讨论】:

    标签: rust


    【解决方案1】:

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

    没有办法将结构本身的生命周期作为生命周期参数传递。您唯一能做的就是从MyGame 中删除game_window 字段并将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 */
        });
    }
    

    【讨论】:

    • 谢谢,我明白了这个原因,但它不起作用仍然很奇怪......也想不出一个编译器可以轻松验证的安全和通用的解决方案,一切都取决于依赖关系和初始化/销毁顺序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    相关资源
    最近更新 更多