0

考え方は単純です。いくつかの Windows を持つアプリがいくつかあります。Windows には、アプリへの何らかのタイプの参照があります。彼らはお互いの方法を使用する必要があります。大雑把なコードをいくつか作成しましたが、1 つの問題を解決すると、新しい問題が発生します。

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 HellWin : s とApps の両方を所有するブローカーを実装し、 ID を介してWin/Appを相互に参照させます。対話が必要な場合、Win/Appはイベントをブローカに送信しますが、これは非同期で処理されます。

これは、コールバック地獄を取得するという犠牲を払って、所有権グラフを解きほぐします。

于 2015-08-06T14:29:15.550 に答える