Rust 无法作为不可变借用,因为它在函数参数中也是作为可变借用的

Rust 无法作为不可变借用,因为它在函数参数中也是作为可变借用的,rust,borrow-checker,Rust,Borrow Checker,这里发生了什么事 给出此错误: error[E0502]:无法将'n'作为不可变项借用,因为它也是作为可变项借用的 --> :17:11 | 17 | n.set(n.get()+1); |-^-可变借用在此处结束 | | | ||此处发生不可变借用 |可变借用发生在这里 但是,如果您只需将代码更改为此,它就可以工作: fn main() { let mut n = Number{ num: 0 }; let tmp = n.get() + 1; n.s

这里发生了什么事

给出此错误:

error[E0502]:无法将'n'作为不可变项借用,因为它也是作为可变项借用的
--> :17:11
|
17 | n.set(n.get()+1);
|-^-可变借用在此处结束
|     |     |
||此处发生不可变借用
|可变借用发生在这里
但是,如果您只需将代码更改为此,它就可以工作:

fn main() {
    let mut n = Number{ num: 0 };
    let tmp = n.get() + 1;
    n.set(tmp);
}
对我来说,这些看起来完全相同——我的意思是,我希望在编译期间将前者转换为后者。在评估下一级函数调用之前,是否评估所有函数参数?

此行:

n.set(n.get() + 1);
脱去糖衣

Number::set(&mut n, n.get() + 1);
现在,错误消息可能会更清楚一些:

error[E0502]:无法将'n'作为不可变项借用,因为它也是作为可变项借用的
-->

现在,问题应该显而易见了。交换前两行可以解决这个问题,但Rust不能进行那种控制流分析

它最初创建为,现在集成到。如果您使用的是Rust 1.36或更新版本,NLL将自动启用,并且会自动关闭

另见:


您可以找到借阅检查流程的详细信息。这里有一个解决方案,并有一个关于的讨论,请看一看。它深入地解释了这个问题。有更多关于该问题的后续帖子。相关:
Number::set(&mut n, n.get() + 1);
let arg1 = &mut n;
let arg2 = n.get() + 1;
Number::set(arg1, arg2);