不能把"自我"借给不可变因为"self.chars"也被借用为可变的

osa*_*amu 0 rust

我需要对一个struct字段的不可变访问和对另一个struct字段的可变访问,但它们必须相互堆叠.我多次遇到这个问题而且我不知道如何解决这个问题.

use std::collections::HashMap;

struct Bar;
impl Bar {
    fn get(&self) -> i32 {
        100
    }
}
struct Foo {
    chars: HashMap<char, i32>,
    b: Bar,
}

impl Foo {
    fn run(&mut self) {
        self.chars.entry('c').or_insert_with(|| self.b.get() * 100);
    }
}

fn main() {
    let mut m = Foo {
        chars: HashMap::new(),
        b: Bar,
    };
    m.run();
}
Run Code Online (Sandbox Code Playgroud)
error[E0502]: cannot borrow `self` as immutable because `self.chars` is also borrowed as mutable
  --> src/main.rs:16:46
   |
16 |         self.chars.entry('c').or_insert_with(|| self.b.get() * 100);
   |         ----------                           ^^ ----              - mutable borrow ends here
   |         |                                    |  |
   |         |                                    |  borrow occurs due to use of `self` in closure
   |         |                                    immutable borrow occurs here
   |         mutable borrow occurs here
Run Code Online (Sandbox Code Playgroud)

vij*_*joc 6

正如编译器所说的那样,问题在于你正在尝试self可变地不可变地借用.正如Stefan指出的,借用检查器无法区分跨越闭包边界的字段访问,因此我们需要通过更明确地了解我们想要借用的内容并传递给闭包来帮助它.

一种方法是在以下内容中取出引用self.b并使用它or_insert_with():

use std::collections::HashMap;

struct Bar;
impl Bar {
    fn get(&self) -> i32 {
        100
    }
}
struct Foo {
    chars: HashMap<char, i32>,
    b: Bar,
}

impl Foo {
    fn run(&mut self) {
        let b = &self.b;
        self.chars.entry('c').or_insert_with(|| b.get() * 100);
    }
}

fn main() {
    let mut m = Foo {
        chars: HashMap::new(),
        b: Bar,
    };
    m.run();
}
Run Code Online (Sandbox Code Playgroud)

  • 也许还可以解释问题是什么:"借用检查器可以区分对不同字段的访问,但不能跨越函数/闭包边界.如果在闭包中使用`self`,它将借用`self`,而不仅仅是你的字段'重新尝试在关闭中访问". (4认同)

归档时间:

查看次数:

272 次

最近记录:

8 年 前