不能将HashMap借用为可变,因为它也被借用为不可变的

时间:2018-03-11 07:01:07

标签: rust

这个问题被问了几十万次,但它始终有一种独特的解决方案。我明白为什么会发生这种情况以及如何修复它,但我的修复很难看,我可能会遗漏一些东西。

use std::collections::HashMap;

fn main() {
    let mut s = Trololo { data: HashMap::new() };
    s.doit();
    s.doit_ugly();
}

struct Trololo {
    data: HashMap<&'static str, String>
}

impl Trololo {
    pub fn doit(&mut self) {
        let a = self.data.get("some key");
        // do something with a
        if a.is_some() {
            // here I don't need 'a' anymore, but because self.data borrowed immutably I can't do anything with it mutably
            self.data.insert("another key", String::new());
        }
    }

    pub fn doit_ugly(&mut self) {
        let mut mutate = false;
        {
            let a = self.data.get("some key");
            // do something with a
            if a.is_some() {
                mutate = true;
            }
        }   // borrow end here, so I can borrow self.data mutably now
        if mutate {
            self.data.insert("another key", String::new());
        }

    }
}

方法doit()中的问题。我无法借用self.data作为可变对象,因为a包含对不可变借用self.data的引用。

可以在doit_ugly()方法中修复此问题,但看起来很糟糕。

有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

在查看the description for error 502之后,我只建议一个选项:将可变借位置于可变对象之后,并使用原始数据检查if语句而不是a:< / p>

pub fn doit(&mut self) {
    if self.data.get("some key").is_some() {
        self.data.insert("another key", String::new());
    }

    let a = self.data.get("some key");
}

答案 1 :(得分:0)

您可以使用map

self.data.get("some key")
    .map(|a| println!("{:?}", a)) // do something with a if there is some a
    .map(|_| self.data.insert("another key", String::new())); 

它将a映射到(),启用self.data.insert