如何为观察者设计模型保持(自捕获)闭包

问题描述 投票:0回答:1

我试图将多个回调作为闭包保存,但我在它们的生命周期中遇到了麻烦:

pub type WriteCallback = Box<dyn FnMut(u8, u8) -> u8>;

pub struct AddressBus {
    on_write_listeners: HashMap<usize, WriteCallback>,
}

impl AddressBus {
    pub fn on_write(&mut self, address: usize, callback: WriteCallback) {
        self.on_write_listeners.insert(address, callback);
    }
}

// component.rs

pub struct Component {
    value: u8,
    address_bus: Rc<RefCell<AddressBus>>,
}

impl Component {
    pub fn new(address_bus: Rc<RefCell<AddressBus>>) -> Self {
        Component {
            value: 0,
            address_bus: address_bus.clone(),
        }
    }

    pub fn init(&mut self) {
        self.address_bus.clone().borrow_mut().on_write(0xFF54, Box::new(|old, new| {
            // I want to use self here e.g: self.value = new;
            new
        }));

        self.address_bus.clone().borrow_mut().on_write(0xFF55, Box::new(|old, new| {
            // I want to use self here
            new
        }));
    }
 }

但无论我尝试什么,我总是得到:

32 |       pub fn init(&mut self) {
   |                   - let's call the lifetime of this reference `'1`
33 |           self.address_bus.clone().borrow_mut().on_write(0xFF54, Box::new(|old, new| {
   |  ________________________________________________________________^
34 | |             // I want to use self here
35 | |             self.value = new;
36 | |             new
37 | |         }));
   | |__________^ cast requires that `'1` must outlive `'static`

有没有办法解决这个问题,或者我是否需要更改为不同的设计模式?知道我正在使用 wasm-bindgen 并且无法在我的结构中使用生命周期引用。

我尝试像

move
一样使用
self.address_bus.clone().borrow_mut().on_write(0xFF54, Box::new(move ...
。它可以工作,但它也会消耗
self
并且我无法再使用该结构。

rust design-patterns closures lifetime
1个回答
0
投票

我按照 cdhowie 的建议,使用

Rc<RefCell<Self>>
:

设法使其工作
fn init(rc: Rc<RefCell<Self>>) {
        let rc2 = rc.clone();

        rc.clone().borrow_mut().address_bus.borrow_mut().on_write(0xFF54, Box::new(move |old, new| {
            new
        }));
        rc2.clone().borrow_mut().address_bus.borrow_mut().on_write(0xFF55, Box::new(move |old, new| {
            rc2.borrow_mut().value = old;
            new
        }));
    }

为了修改两者中的

self
,我需要克隆引用并移动它。

© www.soinside.com 2019 - 2024. All rights reserved.