【问题标题】:cannot borrow `self.hash` as mutable because it is also borrowed as immutable [duplicate]不能借用`self.hash`作为可变的,因为它也被借用为不可变的[重复]
【发布时间】:2016-03-20 19:38:58
【问题描述】:

我正在努力完成这项工作

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

(游戏笔)[http://is.gd/hDLEaL]

但我明白了

<anon>:25:33: 25:37 error: cannot borrow `*self` as mutable because `self.hash` is also borrowed as immutable [E0502]

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

【问题讨论】:

  • 尝试将match self.hash.get(&amp;id) {改成match self.hash.get(&amp;id).cloned() {和*value改成value
  • 谢谢,很有意义。它有效!
  • 那是因为 get 返回 Option&lt;&amp;u32&gt; 但您实际上不需要借用的引用,而只需要值。所以cloned() 将Option&lt;&amp;T&gt; 转换为Option&lt;T&gt; 并释放借用。
  • 对于你想做的事情,有一个更好的成语,.entry().or_insert():doc.rust-lang.org/std/collections/hash_map/…

标签: rust


【解决方案1】:

更新

在 Rust 中添加 Non-Lexical Lifetimes 后,如果您将 1.31.0 用于 Rust 2018 版,将1.36.0 用于 Rust 2015 版,则此问题应该不再是问题。

原答案

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

Code

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

【讨论】:

  • 非常感谢您。我以为我要疯了。
猜你喜欢
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多