如果值超过闭包,在闭包之间共享引用的正确方法是什么? [英] What is the right way to share a reference between closures if the value outlives the closures?
问题描述
我想在两个闭包之间共享一个引用;在一个封闭中可变.这是一个人为的情况,但我觉得在学习 Rust 的背景下很有趣.
I want to share a reference between two closures; mutably in one closure. This is an artificial situation, but I find it interesting in the context of learning Rust.
为了使它工作,我不得不使用Rc
、Weak
和RefCell
.有没有更简单的方法来实现这一点?
In order to make it work, I had to make use of Rc
, Weak
, and RefCell
. Is there a simpler way of achieving this?
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
struct Foo {
i: i32,
}
impl Foo {
fn get(&self) -> i32 {
self.i
}
fn incr(&mut self) {
self.i += 1
}
}
fn retry<O, N>(mut operation: O, mut notify: N) -> i32
where
O: FnMut() -> i32,
N: FnMut() -> (),
{
operation();
notify();
operation()
}
fn something(f: &mut Foo) {
let f_rc = Rc::new(RefCell::new(f));
let f_weak = Rc::downgrade(&f_rc);
let operation = || {
// f.get()
let cell = f_weak.upgrade().unwrap();
let f = cell.borrow();
f.get()
};
let notify = || {
// f.incr();
let cell = f_weak.upgrade().unwrap();
let mut f = cell.borrow_mut();
f.incr();
};
retry(operation, notify);
println!("{:?}", f_rc);
}
fn main() {
let mut f = Foo { i: 1 };
something(&mut f);
}
推荐答案
这里不需要引用计数,因为实体的寿命比任何闭包都长.你可以逃脱:
Reference counting is unnecessary here because the entity lives longer than any of the closures. You can get away with:
fn something(f: &mut Foo) {
let f = RefCell::new(f);
let operation = || f.borrow().get();
let notify = || {
f.borrow_mut().incr();
};
retry(operation, notify);
println!("{:?}", f);
}
这很简单.
然而,RefCell
的使用对于将别名异或可变性的实施从编译时移到运行时是必要的.
The use of RefCell
, however, is necessary to move the enforcement of the Aliasing XOR Mutability from compile-time to run-time.
这篇关于如果值超过闭包,在闭包之间共享引用的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!