此代码段
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});
}
}
不起作用,因为我们不能自己借两次
error: closure requires unique access to `self` but `self.local_ids` is already borrowed [E0500]
这可以在没有第二次密钥查找的情况下修复吗?
这与Rust: HashMap borrow issue when trying to implement find or insert非常相似,但API发生了重大变化。
上面的find_with_or_insert_with回答似乎没有映射到当前的api。
答案 0 :(得分:5)
问题是闭包捕获self
,而只需要捕获last_id
字段的可变引用。
Rust允许我们对不同的字段进行独立的可变借用,因此我们可以利用它来获得优势,并将last_id
字段的可变引用传递给闭包。
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 });
}
}
当我们在闭包中使用表达式self.last_id
时,闭包直接捕获self
,但Rust没有意识到借用是独立的,所以我们需要更明确。