Давайте разберемся с ними один за другим.
print_max_1
Здесь largest
- это изменяемая переменная, которая содержит неизменную ссылку на u16
(т.е. она содержит &u16
). В пределах l oop, number
также является &u16
, который, как и largest
, заимствован из number_list
. И number
, и larger
неявно разыменовываются для выполнения сравнения. Если значение, на которое ссылается number
, превышает значение, на которое ссылается larger
, вы сохраняете копию неизменяемой ссылки, содержащейся в number
, в largest
.
print_max_2
В этом случае, поскольку number_list
само заимствовано, анализ print_max_2
идентичен print_max_1
.
print_max_3
Здесь largest
представляет собой u16
. Вы правы, что number_list[0]
скопировано, но стоит отметить, что эта копия дешевая . В пределах l oop каждый элемент number_list
копируется и сохраняется непосредственно в number
. Если number
больше largest
, вы сохраните новое наибольшее значение непосредственно в largest
. Это наиболее оптимальная из трех написанных вами реализаций, поскольку вы избавляетесь от всей ненужной косвенности, которую представляют ссылки (т. Е. Указатели).
print_max_4
Еще раз Вы сохраняете ссылку на первый элемент number_list
в largest
, т.е. largest
- это &u16
. Аналогично, как и в случае print_max_3
, number
- это u16
, в котором будут храниться копии элементов из number_list
. Однако, как вы заметили, эта функция является дочерним объектом проблемы.
Внутри l oop компилятор укажет на две ошибки:
- Вы пытаетесь сравнить два разных типа которые не имеют
PartialOrder
, а именно largest
, который является &u16
и number
, который является u16
. Русту не нужно пытаться угадать, что вы имеете в виду под этим сравнением, поэтому, чтобы исправить это, вы должны сделать оба типа number
и largest
одного типа. В этом случае вам нужно явно разыменовать largest
с помощью оператора *
, который позволит вам сравнить u16
, на который он указывает, с u16
, содержащимся в number
. Это окончательное сравнение выглядит как if number > *largest { ... }
- Вы пытаетесь сохранить
u16
в переменной типа &u16
, что не имеет смысла. К сожалению, здесь вы наткнетесь на стену. В пределах l oop все, что у вас есть, - это значение числа, которое вы скопировали с number_list
, но largest
должно содержать ссылку до u16
. Мы не можем просто заимствовать number
здесь (например, записывая largest = &number
), так как number
будет отброшено (то есть go вне области видимости) в конце l oop. Единственный способ разрешения - это возврат к print_max_2
путем сохранения самого максимального значения вместо указателя на него.
Относительно того, является ли for number in number_list
ярлык для for number in number_list.iter()
, ответ твердый нет . Первый из них станет владельцем number_list
, и на каждой итерации number
станет владельцем следующего значения в number_list
. В отличие от этого, последний выполняет только заимствование, и во время каждой итерации l oop, number
получает неизменную ссылку на следующий элемент number_list
.
В этом конкретном случае c эти две операции кажутся идентичными, поскольку получение права владения неизменной ссылкой просто влечет за собой создание копии, что оставляет первоначального владельца нетронутым. Для получения дополнительной информации см. этот ответ на связанный вопрос о разнице между .into_iter()
и .iter()
.