在闭包中编辑 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
有人知道我需要做什么吗?
提前感谢您的回复。
Rc
s 由克隆共享,这会增加它们的引用计数。但是您将对它的引用传递给闭包,这可能首先破坏了使用 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
}));
我想在实现 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
有人知道我需要做什么吗? 提前感谢您的回复。
Rc
s 由克隆共享,这会增加它们的引用计数。但是您将对它的引用传递给闭包,这可能首先破坏了使用 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
}));