Осмысливаем области видимости (Thinking in scopes) Rust
Вот код:
let mut x = 5;
let y = &mut x;
*y += 1;
println!("{}", x);
Этот код выдает нам такую ошибку:
error: cannot borrow `x` as immutable because it is also borrowed as mutable
println!("{}", x);
^
Это потому, что мы нарушили правила: у нас есть изменяемая ссылка &mut T, указывающая на x, и поэтому мы не можем создать какую-либо &T. Одно из двух. Примечание подсказывает как следует рассматривать эту проблему:
note: previous borrow ends here
fn main() {
}
^
Вопрос
Почему мой код прекрасно компилируется и исполняется?
Мой код:
#![allow(unused_variables)]
fn main() {
let mut x = 5;
let y = &mut x;
*y += 1;
println!("{}", x);
}
Выход:
D:\Source\RUST\playground> cargo build
Compiling playground v0.1.0 (D:\Source\RUST\playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.36s
D:\Source\RUST\playground> cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.01s
Running `target\debug\playground.exe`
6
Ответы (1 шт):
Эта версия RPL достаточно сильно устарела, актуальную можно найти здесь.
Сейчас в Rust область видимости ссылки (reference’s scope) начинается её объявлением и заканчивается её последним использованием. Поэтому в примере всё и в порядке, к моменту println! y уже вышла из области видимости и владение (ownership) вернулось к x.
Если в println!, например, попробовать распечатать y:
println!("{} {}", x, y);
то увидишь ту же самую ошибку:
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> src/main.rs:5:23
|
3 | let y = &mut x;
| ------ mutable borrow occurs here
4 | *y += 1; //
5 | println!("{} {}", x, y);
| ^ - mutable borrow later used here
| |
| immutable borrow occurs here