Не может заимствовать как неизменяемый, поскольку он также заимствован как изменяемый в аргументах функции
Что здесь происходит ( детская площадка )?
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 --> :17:11 | 17 | n.set(n.get() + 1); | - ^ - mutable borrow ends here | | | | | immutable borrow occurs here | mutable borrow occurs here
Однако, если вы просто меняете код на это, он работает:
- Как остановить итерацию и вернуть ошибку, когда Iterator :: map возвращает результат: Err?
- Инициализировать большой массив фиксированного размера с типами без копирования
- Почему законно занимать временное?
- Каков правильный способ вернуть Итератор (или любой другой признак)?
- Как преобразовать строку C в строку Rust и вернуться через FFI?
fn main() { let mut n = Number{ num: 0 }; let tmp = n.get() + 1; n.set(tmp); }
Для меня они выглядят точно эквивалентно – я имею в виду, я бы ожидал, что первое будет преобразовано в последнее во время компиляции. Разве Rust не оценивает все функциональные параметры перед оценкой вызова функции следующего уровня?
- Почему заем все еще держится в блоке else, если пусть?
- Почему мой пользователь не вводит корректное соответствие stdin?
- Могу ли я написать Итератор, который сам мутирует, а затем дает ссылку на себя?
- Вектор объектов, принадлежащих признаку
- Как мне взять RefCell , найти ключ и вернуть ссылку на результат?
- Почему Iterator :: take_while получает право собственности на iterator?
- Как вызвать метод, когда свойство и структура используют одно и то же имя?
- Как я могу собрать в массив?
Эта строка:
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 --> :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);
Теперь должно быть очевидно, что не так. Переставляя эти первые две строки, это исправляет, но Rust не делает такого анализа управления streamом.
Это было впервые создано как ошибка # 6268 , теперь она интегрирована в RFC 811 .
Начиная с 1.25.0-ночного 2018-01-13, можно использовать несексные времена жизни . Если вы запустите свой пример в ночном режиме Rust и включите шлюз функций NLL, используя #![feature(nll)]
, он теперь будет компилироваться без ошибок .