【问题标题】:What is the right way to share a reference between closures if the value outlives the closures?如果价值超过闭包,那么在闭包之间共享引用的正确方法是什么?
【发布时间】:2018-09-24 00:17:19
【问题描述】:

我想在两个闭包之间共享一个引用;可变地在一个闭包中。这是人为的情况,但我发现在学习 Rust 的背景下很有趣。

为了让它工作,我不得不使用RcWeakRefCell。有没有更简单的方法来实现这一点?

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);
}

【问题讨论】:

    标签: rust


    【解决方案1】:

    这里不需要引用计数,因为实体的寿命比任何闭包都长。你可以逃脱:

    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 的使用对于将 Aliasing XOR Mutability 的实施从编译时转移到运行时是必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多