0

这个想法很简单:有些应用程序有一些 Windows。Windows 对其应用程序有某种类型的引用。他们需要使用彼此的方法。我已经编写了一些粗略的代码,但是当我解决一个问题时,我得到了一个新问题。

struct Win {
      x: i32,
      y: i32,
      last_event: u32, // just for testing
      app: App,
}

impl Win {
    pub fn new(app: &mut App, x: i32, y: i32) -> Win {
        let mut win = Win{app: *app, x: x, y: y, last_event: 0};
        app.add_window(&mut win);
        win
    }

    fn add_window_to_app(&mut self, app: &mut App) {
        app.add_window(self);
    }

    pub fn on_event(&mut self, event: u32, param1: u32, param2: u32) {
        self.last_event = event;
    }
}

struct App {
    pid: u32,
    windows: Vec<Win>,
}

impl App {
    pub fn new(pid: u32) -> App {
        let app = App{pid: pid, windows: Vec::<Win>::new()};
        app
    }

    pub fn add_window(&mut self, win: &mut Win) {
        self.windows.push(*win);
    }

    pub fn on_event(&mut self, win: &mut Win, event: u32, param1: u32, param2: u32) {
        win.on_event(event, param1, param2);
    }
}

fn main() {
    let mut app = App::new(1);
}
4

1 回答 1

1

理想:对依赖图进行排序以使其成为非循环的,然后借用检查将开箱即用。


实际:由于现实往往比期望的更复杂,理想的情况可能是不可能的或不切实际的。在这种情况下,您可以使用RefCell(from std::cell) 将所有权检查从编译时移至运行时。

这仍然禁止别名 + 可变性(因此您不能改变Win您已经在其他地方使用的引用的 a),但推迟到运行时检查,但会受到少量惩罚。


Callback Hell:实现一个broker,他同时拥有Wins和Apps,并通过ID让Win/App相互引用;当需要交互时,Win/App向代理发送一个异步处理的事件。

这以获取回调地狱为代价解开了所有权图。

于 2015-08-06T14:29:15.550 回答