I have a data type containing a RefCell<_>
that contains a complex structure; I'd like to return a smart pointer of some kind to a specific thing within the structure. At present I'm saving the specific thing in the structure as an Rc<T>
so that I can clone and return the Rc<T>
. However, I'd like to see if there's a more efficient way to do it. That is, given
a RefCell<T>
where T
includes an inner S
, can I convert the borrowed Ref<T>
into a Ref<S>
?
The type in question, Value
represents a data value that can be returned as a number of different types. Computing one of these results can be expensive; and usually code will stick to one of the result types for long periods of time. Consequently, I use a RefCell and interior mutability to cache the value.
The type looks something like this (after I remove the irrelevant portions):
#[derive(Clone, Debug)]
pub struct Value {
inner: Rc<InnerValue>,
}
#[derive(Debug)]
struct InnerValue {
data_rep: RefCell<DataRep>,
// ...
}
// The data representation for Values.
#[derive(Clone, Debug)]
enum DataRep {
Int(i64),
List(Rc<Vec<Value>>),
None,
}
The DataRep
enum holds the cached data representation. The List
option stores the list in an Rc<_>
so that I can clone and return a smart pointer, Rc<Vec<Value>>
rather than Ref<DataRep>
:
pub fn as_list(&self) -> Result<Rc<Vec<Value>>, ResultCode> {
// FIRST, if we have the desired type, return it.
if let DataRep::List(list) = &*self.inner.data_rep.borrow() {
return Ok(list.clone());
}
// NEXT, try to compute and cache the list
...
}
Is there a way to return Ref<Vec<Value>>
(or something similar) in this case without wrapping the Vec<Value>
in an Rc<T>
?