不能借用为不可变的,因为它在函数参数中也被借用为可变的
Cannot borrow as immutable because it is also borrowed as mutable in function arguments
这是怎么回事 (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);
}
出现此错误:
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
但是,如果您只需将代码更改为这样它就可以工作:
fn main() {
let mut n = Number{ num: 0 };
let tmp = n.get() + 1;
n.set(tmp);
}
对我来说,它们看起来完全相同 - 我的意思是,我希望前者在编译期间转换为后者。 Rust 不会在评估下一级函数调用之前评估所有函数参数吗?
这一行:
n.set(n.get() + 1);
脱糖成
Number::set(&mut n, n.get() + 1);
错误信息现在可能更清楚了:
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
当 Rust 从左到右评估参数时,该代码等同于:
let arg1 = &mut n;
let arg2 = n.get() + 1;
Number::set(arg1, arg2);
Editor's note: This code example gives an intuitive sense of the underlying problem, but isn't completely accurate. The expanded code still fails even with non-lexical lifetimes, but the original code compiles. For the full description of the problem, review the comments in the original implementation of the borrow checker
现在应该很明显出了什么问题。交换前两行可以解决这个问题,但 Rust 不会进行那种控制流分析。
这最初创建为 bug #6268, now it is integrated into RFC 2094, non-lexical-lifetimes. If you use Rust 1.36 or newer, NLL is enabled automatically and your code will now compile without an error。
另请参阅:
这是怎么回事 (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);
}
出现此错误:
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
但是,如果您只需将代码更改为这样它就可以工作:
fn main() {
let mut n = Number{ num: 0 };
let tmp = n.get() + 1;
n.set(tmp);
}
对我来说,它们看起来完全相同 - 我的意思是,我希望前者在编译期间转换为后者。 Rust 不会在评估下一级函数调用之前评估所有函数参数吗?
这一行:
n.set(n.get() + 1);
脱糖成
Number::set(&mut n, n.get() + 1);
错误信息现在可能更清楚了:
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
当 Rust 从左到右评估参数时,该代码等同于:
let arg1 = &mut n;
let arg2 = n.get() + 1;
Number::set(arg1, arg2);
Editor's note: This code example gives an intuitive sense of the underlying problem, but isn't completely accurate. The expanded code still fails even with non-lexical lifetimes, but the original code compiles. For the full description of the problem, review the comments in the original implementation of the borrow checker
现在应该很明显出了什么问题。交换前两行可以解决这个问题,但 Rust 不会进行那种控制流分析。
这最初创建为 bug #6268, now it is integrated into RFC 2094, non-lexical-lifetimes. If you use Rust 1.36 or newer, NLL is enabled automatically and your code will now compile without an error。
另请参阅: