我试图将多个回调作为闭包保存,但我在它们的生命周期中遇到了麻烦:
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
并且我无法再使用该结构。
我按照 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
,我需要克隆引用并移动它。