Как преобразовать пример «наибольшее значение в Vec» в книге Rust, чтобы не использовать черту «Копировать»? - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь выполнить упражнение "предоставлено читателю" в книге о ржавчине 2018 года . Пример, который они имеют, 10-15, использует черту Copy. Однако они рекомендуют реализовать то же самое без Copy, и я действительно боролся с этим.

Без Copy я не могу использовать largest = list[0]. Компилятор рекомендует использовать ссылку вместо этого. Я делаю так, превращая largest в &T. Затем компилятор жалуется, что largest, используемый в сравнении, является &T, а не T, поэтому я изменяю его на *largest для разыменования указателя. Это идет хорошо, но затем натыкается на largest = item, с жалобами на T вместо &T. Я переключаюсь на largest = &item. Тогда я получаю ошибку, с которой не могу разобраться:

error[E0597]: `item` does not live long enough
 --> src/main.rs:6:24
  |
6 |             largest = &item;
  |                        ^^^^ borrowed value does not live long enough
7 |         }
8 |     }
  |     - borrowed value only lives until here
  |
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 1:1...

Я не понимаю, как продлить жизнь этой ценности. Он живет и умирает в list.iter(). Как я могу расширить его, используя только ссылки?

Вот мой код для справки:

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];

    for &item in list.iter() {
        if item > *largest {
            largest = &item;
        }
    }

    largest
}

1 Ответ

0 голосов
/ 12 ноября 2018

Когда вы пишете for &item, это разрушает каждую ссылку, возвращаемую итератором, делая тип item T. Вы не хотите разрушать эти ссылки, вы хотите сохранить их! В противном случае, когда вы берете ссылку на item, вы берете ссылку на локальную переменную, которую вы не можете вернуть, потому что локальные переменные не живут достаточно долго.

fn largest<T: PartialOrd>(list: &[T]) -> &T {
    let mut largest = &list[0];

    for item in list.iter() {
        if item > largest {
            largest = item;
        }
    }

    largest
}

Обратите также внимание на то, как мы можем сравнивать ссылки напрямую, потому что ссылки на типы, реализующие PartialOrd, также реализуют PartialOrd, откладывая сравнение с их ссылками (то есть это не сравнение указателей, в отличие от необработанные указатели ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...