Невозможно передать изменяемую ссылку на себя напрямую - PullRequest
0 голосов
/ 02 октября 2019

В настоящее время я работаю над реализацией Rust в связанном списке. Прежде всего, я прочитал документацию по ржавчине на Learning Rust со слишком большим количеством связанных списков . Но я все еще немного пытаюсь понять ошибки, возникающие при реализации черты into().

Вот как я это реализовал (и похоже, теперь работает):

impl<T> Into<Vec<T>> for SimpleLinkedList<T> {
    fn into(self) -> Vec<T> {
        let mut res = Vec::new();
        let mut mutable_to_self = self;

        fn into_rec<T>(list: &mut SimpleLinkedList<T>, v: &mut Vec<T>) {
            if let Some(x) = list.pop() {
                into_rec(list, v);
                v.push(x);
            }
        }

        into_rec(&mut mutable_to_self, &mut res);
        res

Что меня смущает, так это необходимость mutable_to_self. Сначала я попытался избавиться от этой переменной и просто передать &mut self непосредственно в into_rec() (для меня это абсолютно то же самое). Однако когда я это делаю, я получаю:

error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
  --> src/lib.rs:93:18
   |
82 |     fn into(self) -> Vec<T> {
   |             ---- help: consider changing this to be mutable: `mut self`
...
93 |         into_rec(&mut self, &mut res);
   |                  ^^^^^^^^^ cannot borrow as mutable

error: aborting due to previous error

For more information about this error, try `rustc --explain E0596`.
error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable
  --> src/lib.rs:93:18
   |
82 |     fn into(self) -> Vec<T> {
   |             ---- help: consider changing this to be mutable: `mut self`
...
93 |         into_rec(&mut self, &mut res);
   |                  ^^^^^^^^^ cannot borrow as mutable

Так что я не уверен, что не так со второй реализацией.

1 Ответ

0 голосов
/ 02 октября 2019

Проблема в том, что собственные переменные, предназначенные для прямой изменчивости, должны быть непостоянно связаны.

Когда вы объявляете переменную или аргумент функции, это может быть объединено как объявление привязки значения для некоторого имени - либо с ключевым словом let, либо со списком аргументов в квадратных скобках. Эта привязка может быть изменяемой или неизменной, в зависимости от наличия или отсутствия ключевого слова mut.

Если вы объявите привязку как неизменную, т.е. пропустите ключевое слово mut, компилятор заявляет, что вы не получитеуникальная ссылка на него (и, следовательно, не будет изменять значение, по модулю любых UnsafeCell s внутри него). Поэтому, если вы пытаетесь получить &mut ссылку на него, это ошибка.

Чтобы исправить ошибку, вы можете либо перепривязать переменную, изменяя, эффективно отбрасывая предыдущую привязку (если значение равноне Copy), или связывайте его с первого взгляда - так как это часть привязки, а не объявления переменной, ее можно использовать как в объявлении функции, так и в операторе let.

...