为什么在涉及 += 运算符的同一表达式中使用可变引用和不可变引用有时似乎是允许的,有时却是不允许的?

and*_*sdr 2 rust borrow-checker

在下面的代码示例中,我试图以四种不同的方式通过a对结构X的可变引用来增加结构的成员变量。在这里,编译器为由 表示的行给出以下错误B

error[E0502]: cannot borrow `*x` as immutable because it is also borrowed as mutable
  --> src\main.rs:17:23
   |
17 |     *x.get_a_mut() += x.get_a(); //B DOESN'T COMPILE
   |     ------------------^--------
   |     ||                |
   |     ||                immutable borrow occurs here
   |     |mutable borrow occurs here
   |     mutable borrow later used here
Run Code Online (Sandbox Code Playgroud)

如果是使用可变和不可变的参照问题a在同一个表达式,为什么CD编译?

struct X {
    a: i64,
}

impl X {
    pub fn get_a_mut(&mut self) -> &mut i64 {
        return &mut self.a;
    }

    pub fn get_a(&self) -> &i64 {
        return &self.a;
    }
}

fn my_fn(x: &mut X) {
    *x.get_a_mut() += 5; //A
    *x.get_a_mut() += x.get_a(); //B DOESN'T COMPILE
    *x.get_a_mut() += 2 * x.get_a(); //C
    *x.get_a_mut() = x.get_a() + x.get_a(); //D
}

fn main() {
    let mut x = X { a: 50 };
    my_fn(&mut x);
}
Run Code Online (Sandbox Code Playgroud)

pro*_*-fh 9

根据+=文件,您呼叫类似add_assign(lhs: &mut i64, rhs: &i64)的情况下,B和类似add_assign(lhs: &mut i64, rhs: i64)的情况下ACD

如果Arhs是一个常数,不同于x.a; 没问题。

如果Crhs是临时的( 的结果2 * x.get_a())并且不需要保持引用x.a存在;没问题。

如果Drhs是临时的( 的结果x.get_a() + x.get_a())并且不需要保持引用x.a存在;没问题。

但是说到案例Brhs 一个参考x.a;那么这个调用同时对同一数据 ( )使用可变 ( lhs) 和不可变 ( rhs) 引用x.a,这是被禁止的。

你最终可以克隆rhs: *x.get_a_mut() += x.get_a().clone()