Suppose I have some data Bar
(e.g. database client) which I would like to create only once
but lazily for my structure Foo
.
struct Bar;
struct Foo {
bar: Option<Bar>
}
To do this, I check that the field is initialized; if not, I run the async routine.
The result of the routine is then saved as Some
to reuse later.
I know, that Option::get_or_insert_with perfectly fits this scenario, but I have to deal with async, so I do this manually like this.
impl Foo {
pub async fn get_bar(&mut self) -> &Bar {
if let Some(bar) = &self.bar {
return bar;
}
let bar = Self::create_bar().await;
self.bar.insert(bar)
}
/// Long and heavy-resource routine,
/// we want to memoize it.
async fn create_bar() -> Bar {
Bar
}
}
However, this cannot be compiled due to the immutable and mutable borrowing of self.bar
.
Is there a way to do this correctly?
Interestingly the borrow checker is able to infer better lifetimes by using the ref
keyword in your if let
so the following works:
pub async fn get_bar(&mut self) -> &Bar {
if let Some(ref bar) = self.bar {
return bar;
}
let bar = Self::create_bar().await;
self.bar.insert(bar)
}