Cannot borrow as immutable because it is also borrowed as mutable in function arguments

旧巷老猫 提交于 2019-11-26 02:58:49

问题


What is going on here (playground)?

struct Number {
    num: i32
}

impl Number {
    fn set(&mut self, new_num: i32) {
        self.num = new_num;
    }
    fn get(&self) -> i32 {
        self.num
    }
}

fn main() {
    let mut n = Number{ num: 0 };
    n.set(n.get() + 1);
}

Gives this error:

error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable
  --> <anon>:17:11
   |
17 |     n.set(n.get() + 1);
   |     -     ^          - mutable borrow ends here
   |     |     |
   |     |     immutable borrow occurs here
   |     mutable borrow occurs here

However if you simply change the code to this it works:

fn main() {
    let mut n = Number{ num: 0 };
    let tmp = n.get() + 1;
    n.set(tmp);
}

To me those look exactly equivalent - I mean, I would expect the former to be transformed to the latter during compilation. Doesn\'t Rust evaluate all function parameters before evaluating the next-level-up function call?


回答1:


This line:

n.set(n.get() + 1);

is desugared into

Number::set(&mut n, n.get() + 1);

The error message might be a bit more clear now:

error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable
  --> <anon>:18:25
   |
18 |     Number::set(&mut n, n.get() + 1);
   |                      -  ^          - mutable borrow ends here
   |                      |  |
   |                      |  immutable borrow occurs here
   |                      mutable borrow occurs here

As Rust evaluates arguments left to right, that code is equivalent to this:

let arg1 = &mut n;
let arg2 = n.get() + 1;
Number::set(arg1, arg2);

It should now be obvious what is wrong. Swapping those first two lines, fixes this, but Rust does not do that kind of control-flow analysis.

This was first created as bug #6268, now it is integrated into RFC 2094, non-lexical-lifetimes. If you use Rust 2018, NLL is enabled automatically and your code will now compile without an error.



来源:https://stackoverflow.com/questions/41187296/cannot-borrow-as-immutable-because-it-is-also-borrowed-as-mutable-in-function-ar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!