This question already has an answer here:
This snippet
use std::collections::HashMap;
struct Foo {
local_ids: HashMap<i32, i32>,
last_id: i32,
}
impl Foo {
fn foo(&mut self, external_id: i32) {
let id = self.local_ids
.entry(external_id)
.or_insert_with(||{self.last_id += 1; self.last_id});
}
}
Doesn't work because we can't borrow self twice
error: closure requires unique access to `self` but `self.local_ids` is already borrowed [E0500]
Is this possible to fix without a second key lookup?
This is very similar to Rust: HashMap borrow issue when trying to implement find or insert, but the API has changed substantially.
The find_with_or_insert_with answer from above doesn't appear to map to the current api.
The problem is that the closure captures
self
, whereas it only needs to capture a mutable reference to thelast_id
field.Rust allows us to take independent mutable borrows on distinct fields, so we can use that to our advantage and pass a mutable reference to the
last_id
field to the closure.When we use the expression
self.last_id
in the closure, the closure capturesself
directly, but Rust doesn't realize that the borrows are independent, so we need to be more explicit.