使用 Rust 在向量中执行回调

Perform callbacks in a vector with Rust

提问人:user10658782 提问时间:3/15/2023 更新时间:3/15/2023 访问量:73

问:

我有一个对象,其中包含一堆用于回调事件的注册处理程序。

类型定义为 ..

    pub enum ObjectCatalog {
        String(String),
        Callback(Box<dyn FnMut()>),
        Mcu(mcu::MCU),
    }
    pub type VectorOfObjectCatalog = Rc<RefCell<Vec<ObjectCatalog>>>;

在对象中,有一个类型(如下)的变量,其中包含想要了解事件 X 的对象向量。

event_handlers: HashMap<&'a str, shared_types::VectorOfObjectCatalog>,

在我发送事件的函数中,它看起来像这样......

pub fn send_event(&self, event: &'a str) {
            let set = self.event_handlers.get(event);
            match set {
                Some(vec) => {
                    for e in vec.borrow().iter() {
                        match e {
                            shared_types::ObjectCatalog::Callback(callback) => {
                                (callback)();
                            }
                            _ => {}
                        }
                    }
                }
                None => {}
            }
        }

我收到错误

error[E0596]: cannot borrow `*callback` as mutable, as it is behind a `&` reference
   --> src/main.rs:106:33
    |
106 | ...                   (callback)();
    |                       ^^^^^^^^^^ `callback` is a `&` reference, so the data it refers to cannot be borrowed as mutable

为什么?我见过这样的例子,我看不出我做错了什么。

Rust 矢 回调 refcell

评论

2赞 Filipe Rodrigues 3/15/2023
调用 需要可变的。在您的示例中,是不可变的。如果它适合您的用例,则可以改用f: FnMut()fcallbackFn()
2赞 PitaJ 3/15/2023
vec.borrow_mut().iter_mut()
0赞 cafce25 3/15/2023
nit:只有当它是结构的字段时才需要括号,效果很好。callbackcallback()

答:

1赞 user10658782 3/15/2023 #1

是的,谢谢,忘记了iter_mut()....不过需要更多更改,它们就在这里。

pub fn send_event(&self, event: &'a str) {
            let set = self.event_handlers.get(event);
            match set {
                Some(vec) => {
                    for mut e in vec.borrow_mut().iter_mut() {
                        match e {
                            shared_types::ObjectCatalog::Callback(callback) => {
                                (callback)();
                            }
                            _ => {}
                        }
                    }
                }
                None => {}
            }
        }