从 Rc<RefCell<T>> 映射到 Ref<'_, U>

Map from Rc<RefCell<T>> to Ref<'_, U>

我有以下结构:

struct Inner;

enum State {
    A(Inner),
    B,
}

struct Owner {
    state: Rc<RefCell<State>>,
}

我想提供以下界面:

impl Owner {
    fn a(&self) -> Option<Ref<'_, Inner>>;
}

其中 owner.a() 会 return:

这可能吗?我试过查看 Ref::map 但我似乎无法使其与 Rc<RefCell<_>>Option.

一起使用

我现在正在做的解决方法是:

impl Owner {
    fn with_a(&self, mut callback: impl FnMut(&Inner)) {
        match *self.state.borrow() {
            State::A(ref inner) => callback(inner),
            _ => {}
        }
    }
}

playground

owner.a() 不需要增加 Rc 的强计数,因为返回的 Ref 的生命周期已经绑定到 Rc。如果您使用的是 100% Safe Rust 并且它可以编译,您将不会遇到任何内存安全问题,因此您不必担心手动簿记,例如显式递增或递减 Rc 的强计数。 Rc 甚至没有公开更改强计数的方法,这是有充分理由的。这是您想要的函数签名的实现:

use std::rc::Rc;
use std::cell::{RefCell, Ref};

struct Inner;

enum State {
    A(Inner),
    B,
}

struct Owner {
    state: Rc<RefCell<State>>,
}

impl Owner {
    fn a(&self) -> Option<Ref<'_, Inner>> {
        let state_ref = self.state.borrow();
        match *state_ref {
            State::B => None,
            _ => Some(Ref::map(state_ref, |state| match state {
                State::A(inner) => inner,
                _ => unreachable!(),
            })),
        }
    }
}

playground