如何解决自我借用地图.or_insert_with? Rust(1.11)

时间:2016-10-24 01:27:56

标签: dictionary rust

此代码段

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。

1 个答案:

答案 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没有意识到借用是独立的,所以我们需要更明确。