I've been working through the book and am stuck on an exercise. In chapter 13.1, I'm trying to add generic types and the ability to cache multiple values to the memoization cacher. However, I'm getting a borrow error I don't understand.
It seems to me that the immutable borrow within the if let statement should go out of scope before the mutable borrow happens. I've tried enclosing the whole thing in a block but still no cigar. Could someone explain to me the error and recommend a solution?
Thanks in advance.
The code:
use std::collections::HashMap;
use std::hash::Hash;
struct Cacher<T, I, O>
where
T: Fn(&I) -> O,
I: Hash + Eq + Clone,
{
func: T,
values: HashMap<I, O>,
}
impl<T, I, O> Cacher<T, I, O>
where
T: Fn(&I) -> O,
I: Hash + Eq + Clone,
{
fn new(func: T) -> Cacher<T, I, O> {
Cacher {
func,
values: HashMap::new(),
}
}
fn get(&mut self, arg: I) -> &O {
if let Some(res) = self.values.get(&arg) {
return &res;
}
self.values.insert(arg.clone(), (self.func)(&arg));
self.values.get(&arg).unwrap()
}
}
And the error:
error[E0502]: cannot borrow `self.values` as mutable because it is also borrowed as immutable
--> src/lib.rs:30:9
|
25 | fn get(&mut self, arg: I) -> &O {
| - let's call the lifetime of this reference `'1`
26 | if let Some(res) = self.values.get(&arg) {
| ----------- immutable borrow occurs here
27 | return &res;
| ---- returning this value requires that `self.values` is borrowed for `'1`
...
30 | self.values.insert(arg.clone(), (self.func)(&arg));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here