我有以下结构。
struct Inner;
enum State {
A(Inner),
B,
}
struct Owner {
state: Rc<RefCell<State>>,
}
我想提供以下接口。
impl Owner {
fn a(&self) -> Option<Ref<'_, Inner>>;
}
其中 owner.a()
会回来的。
owner.state
匹配 State::A(s)
那么 Some([some ref to s])
的强计数(它增加了 owner.state
并在掉落时减少,同时保证了。RefCell
借款属性)。)None
.这有可能吗?我试着看了一下 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),
_ => {}
}
}
}
owner.a()
不需要增加 Rc
的强数,因为返回的 Ref
'的一生已经与 Rc
. 如果你使用的是100%安全的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!(),
})),
}
}
}