【问题标题】:How to work around self borrowing with map .or_insert_with? Rust (1.11) [duplicate]如何使用 map .or_insert_with 解决自借问题?锈(1.11)[重复]
【发布时间】:2017-03-05 16:58:43
【问题描述】:

这个sn-p

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});
    }
}

不起作用,因为我们不能借用 self 两次

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。

【问题讨论】:

    标签: dictionary rust


    【解决方案1】:

    问题是闭包捕获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并没有意识到借用是独立的,所以我们需要更加明确。

    【讨论】:

    • 谢谢!可以单独借用字段是不是一个新的发展?
    • 不,我认为这已经有很长时间了。
    猜你喜欢
    • 2018-07-17
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多