在闭包中编辑 RefCell

Edit RefCell in closure

我想在实现 Clone 的结构中存储一个闭包,所以我的代码如下:

use std::rc::Rc;

type Closure = Box<dyn Fn() -> ()>;

#[derive(Clone)]
struct A {
    closure: Option<Rc<Closure>>,
}

impl A {
    pub fn new() -> A {
        A { closure: None }
    }

    pub fn closure(&self) -> Option<Rc<Closure>> {
        self.closure.clone()
    }

    pub fn set_closure(&mut self, closure: Closure) -> &mut Self {
        self.closure = Some(Rc::new(closure));
        self
    }
}

fn main() {
    let mut a: A = A::new();

    a.set_closure(Box::new(|| -> () { println!("Works fine!") }));
    (a.closure().unwrap())();
}

现在我想通过借用一个当前作用域的变量来测试这段代码。在 main 函数中保留引用很重要,因为我需要在之后使用它。 我这样编码:

use std::cell::RefCell;

fn main() {
    let mut a: A = A::new();
    let value: Rc<RefCell<i8>> = Rc::new(RefCell::new(0));

    println!("Value = {}", value.borrow());

    a.set_closure(Box::new(|| -> () {
        *value.borrow_mut() = 1;
    }));
    (a.closure().unwrap())();

    println!("New value = {}", value.borrow());
}

但是我得到这个错误:

Compiling playground v0.0.1 (/playground)
error[E0597]: `value` does not live long enough
  --> src/main.rs:34:38
   |
34 |   a.set_closure(Box::new(|| -> () { *value.borrow_mut() = 1; }));
   |                 ---------------------^^^^^---------------------
   |                 |        |           |
   |                 |        |           borrowed value does not live long enough
   |                 |        value captured here
   |                 cast requires that `value` is borrowed for `'static`
...
38 | }
   | - `value` dropped here while still borrowed

有人知道我需要做什么吗? 提前感谢您的回复。

Rcs 由克隆共享,这会增加它们的引用计数。但是您将对它的引用传递给闭包,这可能首先破坏了使用 Rc 的意义。正如错误所说,闭包在 value 被删除后持有对 value 的引用。

你可能打算写这样的东西,克隆 Rc 并将克隆移动到闭包中:

let cloned_value = value.clone();
a.set_closure(Box::new(move || *cloned_value.borrow_mut() = 1));

或者(我的偏好)避免在外部作用域中引入新的绑定:

a.set_closure(Box::new({
    let value = value.clone();
    move || *value.borrow_mut() = 1
}));