使用存储在struct中的回调

时间:2016-07-09 19:10:13

标签: rust borrow-checker

假设我们有一个struct包含回调:

use std::collections::HashMap;

struct Struct {
    callbacks: HashMap<char, Box<Fn(&mut Struct)>>,
}

impl Struct {
    fn new() -> Struct {
        Struct {
            callbacks: HashMap::new(),
        }
    }

    fn add_callback<F: Fn(&mut Struct) + 'static>(&mut self, key: char, callback: F) {
        self.callbacks.insert(key, Box::new(callback));
    }

    fn invoke_callback(&mut self, key: char) {
        if let Some(callback) = self.callbacks.get(&key) {
            callback(self); // NOTE: error here
        }
    }

    fn print(&mut self) {
        println!("Mutably print");
    }
}

fn main() {
    let mut strct = Struct::new();
    strct.add_callback('a', |strct| {
        strct.print();
    });
    strct.invoke_callback('a');
}

使用此代码,我有以下错误:

src/main.rs:20:22: 20:26 error: cannot borrow `*self` as mutable because `self.callbacks` is also borrowed as immutable [E0502]
src/main.rs:20             callback(self);
                                    ^~~~
src/main.rs:19:33: 19:47 note: previous borrow of `self.callbacks` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `self.callbacks` until the borrow ends
src/main.rs:19         if let Some(callback) = self.callbacks.get(&key) {
                                               ^~~~~~~~~~~~~~
src/main.rs:21:10: 21:10 note: previous borrow ends here
src/main.rs:19         if let Some(callback) = self.callbacks.get(&key) {
src/main.rs:20             callback(self);
src/main.rs:21         }
                       ^
error: aborting due to previous error
error: Could not compile `so`.

如何调用对self进行可变引用的回调?

我找到的唯一方法是从HashMap删除回调并将其插回:

fn invoke_callback(&mut self, key: char) {
    if let Some(callback) = self.callbacks.remove(&key) {
        callback(self);
        self.callbacks.insert(key, callback);
    }
}

我想知道是否有更好的方法来调用struct中包含的回调。

0 个答案:

没有答案