Hey everybody,
another lifetime question I'm afraid, any help is appreciated.
Basically I'm trying to implement a caching functionality in my struct, meaning that data is only requested once and then stored, any subsequent requests should only return the already cached data. I want this cache to own the data, and the callee just receives a reference.
A MWE would look like this:
struct Cache {
data: Option<i32>, // init with None
}
impl Cache {
fn get(&mut self) -> &i32 {
if self.data.is_none() {
let new_data = request();
self.data = Some(new_data);
}
&self.data.as_ref().unwrap()
}
}
fn request() -> i32 {
32
}
The problem arises, when I access the data twice:
let mut c = Cache { data: None };
let data1 = c.get();
let data2 = c.get(); // borrow as mutable more than once at a time
println!("{} {}", data1, data2);
I do understand why this does not compile. The question is how to resolve this. Obviously I only need the mutable reference during the update of the local data memory, the returned value works with an immutable reference.
Following solutions I am considering (given that I'm quite new to rust):
- Missing lifetime annotations to achieve what I just described. To my understanding this would require having
&'a mut self
and&'b self
as parameters, which doesn't work. - My approach to implementing a cache is wrong. I don't see how to implement it otherwise, meaning how to split the mutable and immutable part, or how I would structure it differently
-
&
references are not enough. Although I'm not familiar with these yet, maybe I need sth likeRef
orRefCell
? - My concept of ownership is wrong. Given that rust revolves around ownership and borrowing, I keep a close eye that data is not duplicated unnecessarily (I'm working a lot with C#, meaning I'm used to pass-by-reference calls instead of duplication). Meaning, I try to conceptualize which struct should own the data and who gets references. Perhaps, that's also not the way to go about it.
In my code the requested data is not a simple i32
but some kilobytes coming from a http request, hence this caching idea.
Thanks,
Plexian