@boristhecat

Как в этом сниппете кода работает владение (Rust)?

Потихоньку изучаю язык Rust и недавно на одном сайте наткнулся на следующий пример, который не компилируется из-за того, что конструкция loop каким-то образом делает невозможным вызов анонимной функции increase(). Пожалуйста, расскажите, что тут происходит в плане владений и почему компилятору не нравится этот код. ;)
const STOP: i32 = 24;
const INCR: i32 = 2;

fn main() {
    let mut counter = 2;

    let mut increase = || {
        counter += INCR;
    };
    increase();
    println!("counter = {}", counter);

    loop {
        increase();

        println!("counter = {}", counter);

        if counter == STOP {
            break;
        }
    }
}
  • Вопрос задан
  • 152 просмотра
Решения вопроса 1
vabka
@vabka
Токсичный шарпист
Не может одновременно существовать mutable borrow и immutable borrow.
Замыкание берёт mutable borrow и пока замыкание находится в области видимости - никто не может читать значение переменной.

Мне кажется, лучше чем компилятор это не объяснит:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `counter` as immutable because it is also borrowed as mutable
  --> src/main.rs:11:30
   |
7  |     let mut increase = || {
   |                        -- mutable borrow occurs here
8  |         counter += INCR;
   |         ------- first borrow occurs due to use of `counter` in closure
...
11 |     println!("counter = {}", counter);
   |                              ^^^^^^^ immutable borrow occurs here
...
14 |         increase();
   |         -------- mutable borrow later used here
   |
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0502]: cannot borrow `counter` as immutable because it is also borrowed as mutable
  --> src/main.rs:16:34
   |
7  |     let mut increase = || {
   |                        -- mutable borrow occurs here
8  |         counter += INCR;
   |         ------- first borrow occurs due to use of `counter` in closure
...
14 |         increase();
   |         -------- mutable borrow later used here
15 |
16 |         println!("counter = {}", counter);
   |                                  ^^^^^^^ immutable borrow occurs here
   |
   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0503]: cannot use `counter` because it was mutably borrowed
  --> src/main.rs:18:12
   |
7  |     let mut increase = || {
   |                        -- `counter` is borrowed here
8  |         counter += INCR;
   |         ------- borrow occurs due to use of `counter` in closure
...
14 |         increase();
   |         -------- borrow later used here
...
18 |         if counter == STOP {
   |            ^^^^^^^ use of borrowed `counter`

Some errors have detailed explanations: E0502, E0503.
For more information about an error, try `rustc --explain E0502`.
error: could not compile `playground` due to 3 previous errors
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы