不能借用`self.hash`作为可变因为它也被借用为不可变的

Tlm*_*aK0 2 rust

我正努力做到这一点

use std::collections::HashMap;

struct Test1 {
    total: u32,
    hash: HashMap<u32, u32>,
}

impl Test1 {
    fn new() -> Test1 {
        Test1 {
            total: 0,
            hash: HashMap::new(),
        }
    }

    fn add(&mut self) -> u32 {
        self.total += 1;
        self.total
    }

    fn get_or_create(&mut self, id: u32) -> u32 {
        match self.hash.get(&id) {
            Some(value) => *value,
            None => {
                let value = self.add();
                self.hash.insert(id, value);
                value
            }
        }
    }
}

fn main() {
    let mut test = Test1::new();
    println!("{:?}", test.get_or_create(1));
    println!("{:?}", test.get_or_create(1));
}
Run Code Online (Sandbox Code Playgroud)

(围栏)[ http://is.gd/hDLEaL]

但我明白了

<anon>:25:33: 25:37 error: cannot borrow `*self` as mutable because `self.hash` is also borrowed as immutable [E0502]
Run Code Online (Sandbox Code Playgroud)

删除模式匹配并不能解决问题,但我不明白为什么.

XAM*_*cky 6

回答

这是Rust当前状态的问题,借用总是词汇.也就是说,它们持续整个{}或块范围.在match表达式中,执行的借用self继续进入SomeNone阻止.解决此问题的最简单方法是使用if let语句.它提供模式匹配,并允许您self在两个块中使用.

use std::collections::HashMap;

struct Test1 {
    total: u32,
    hash: HashMap<u32, u32>,
}

impl Test1 {
    fn new() -> Test1 {
        Test1 {
            total: 0,
            hash: HashMap::new(),
        }
    }

    fn add(&mut self) -> u32 {
        self.total += 1;
        self.total
    }

    fn get_or_create(&mut self, id: u32) -> u32 {
        if let Some(&value) = self.hash.get(&id) {
            value
        } else {
            let value = self.add();
            self.hash.insert(id, value);
            value
        }
    }
}

fn main() {
    let mut test = Test1::new();
    println!("{:?}", test.get_or_create(1));
    println!("{:?}", test.get_or_create(1));
}
Run Code Online (Sandbox Code Playgroud)