The problem is that the closure captures self
, whereas it only needs to capture a mutable reference to the last_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.
use std::collections::HashMap;
struct Foo {
local_ids: HashMap<i32, i32>,
last_id: i32,
}
impl Foo {
fn foo(&mut self, external_id: i32) {
let last_id = &mut self.last_id;
let id = self.local_ids
.entry(external_id)
.or_insert_with(|| { *last_id += 1; *last_id });
}
}
When we use the expression self.last_id
in the closure, the closure captures self
directly, but Rust doesn't realize that the borrows are independent, so we need to be more explicit.