То, что вы цитируете из книги, является правилом для обычных заданий, таких как let
.Например:
let x = &42;
let ref x = 42;
Но привязка имени в цикле for
немного отличается:
- Зацикливаемое значение преобразуется в итератор (
<v1 as IntoIterator>::into_iter()
) Позволяет вызвать результат этого it
. - Затем
it.next()
вызывается повторно: - Если он возвращает
Some(_)
, то значение этого связано с вашей переменной.Как будто вы написали let Some(ref mut i) = it.next()
или let Some(mut i) = it.next()
.Вот где ref
имеет значение. - Если он возвращает
None
, цикл заканчивается.
Так что в случае цикла for
,ref
и &
не эквивалентны.
Когда вы используете &
в правой части цикла, это не меняет привязку переменной напрямую;Вы просто меняете тип объекта с повторением.Затем все сводится к реализации IntoIterator
для Vec<_>
против того, что для &Vec<_>
.
- Если вы итерируете
Vec<T>
, он становится владельцем вектора, и итерация возвращаетСами ценности.Таким образом, for i in v1
использует вектор, а i
имеет тип содержащихся значений T
. - Если вы итерируете
&Vec<T>
, он заимствует вектор и указатели возврата итерации к содержащимся значениям &T
, поэтому в for i in &v1
тип i
фактически является указателем на значения.Тот же эффект можно получить с помощью for i in v1.iter()
. - . Если вы итерируете
&mut Vec<T>
, то же самое, что и предыдущий, но изменяемый, поэтому итерация возвращает значения типа &mut T
.
.
Вывод состоит в том, что использование ref
в цикле for
, вероятно, не очень полезно.