I have the following code in Rust:
pub struct RegExpFilter {
...
regexp_data: RefCell<Option<RegexpData>>,
...
}
struct RegexpData {
regexp: regex::Regex,
string: String
}
...
pub fn is_regexp_compiled(&self) -> bool {
self.regexp_data.borrow().is_some()
}
pub fn compile_regexp(&self) -> RegexpData {
...
}
fn regexp(&self) -> ®ex::Regex {
if !self.is_regexp_compiled() { // lazy computation that mutates the struct
self.regexp_data.replace(Some(self.compile_regexp()));
}
&self.regexp_data.borrow().as_ref().unwrap().regexp
}
pub fn matches(&self, location: &str) -> bool {
self.regexp().find(location)
}
regexp is calculated lazily, capturing &mut self
i undesired so RefCell
is used.
I'm getting the following message:
&self.regexp_data.borrow().as_ref().unwrap().regexp
| ^-------------------------^^^^^^^^^^^^^^^^^^^^^^^^^
| ||
| |temporary value created here
| returns a value referencing data owned by the current function
The compiler message seems to be clear: Ref
is temporarily created by borrow()
and returned outside. However i believe Option
(self.regexp_data
) is owned by RefCell
which is owned by the struct itself, so it should be fine to use it internally (since the function is not pub
).
I've also tried the following (and it fails with the same message)
fn regexp(&self) -> impl Deref<Target = regex::Regex> + '_ {
if !self.is_regexp_compiled() {
self.regexp_data.replace(Some(self.compile_regexp()));
}
Ref::map(self.regexp_data.borrow(), |it| &it.unwrap().regexp)
}
How can i solve it?
&T
from aRefCell<T>
without keeping theRef<T>
around, its howRefCell
knows whenborrow()
andborrow_mut()
are allowed. See this Q&A. – kmdreko