The borrow checker beat me:
use std::collections::HashMap;
struct Cache {
cache: Vec<HashMap<String, String>>,
}
impl Cache {
fn get(&mut self, index: usize, key: String) -> String {
let mut cache = &mut self.cache[index];
match cache.get(&key) {
Some(r) => {
return r.clone();
}
None => {
let r = "foo".to_string(); // something smart here
cache.insert(key, r.clone());
return r;
}
}
}
}
What I get:
error[E0502]: cannot borrow `*cache` as mutable because it is also borrowed as immutable
--> src/main.rs:16:17
|
10 | match cache.get(&key) {
| ----- immutable borrow occurs here
...
16 | cache.insert(key, r.clone());
| ^^^^^ mutable borrow occurs here
...
19 | }
| - immutable borrow ends here
How can I rewrite my code so that it compiles?
Another approach is to use the
entry
interface. The only downside with this approach is that it (currently) doesn't use theBorrowFrom
infrastructure that theget
method uses, which makes it less flexible. In your case, that isn't a problem sinceget
takes an owned key. The advantage ofentry
is that it only does one hash lookup, whereas usingget
forces you to do two lookups.The borrow checker sees
cache.get
as an immutable borrow, despite the fact that it is returningNone
. The easiest way to change your code is to move the insert out of the match, e.g.: