Come hai detto tu, for
opere prendendo la cosa hai chiesto a iterare, e passando attraverso IntoIterator::into_iter
per produrre il valore iteratore reale. Inoltre, come hai detto, into_iter
prende il soggetto in base al valore.
Così, quando si tenta di iterare su una Vector
direttamente, questo significa che si passa l'intero vettore, per valore, nella sua IntoIterator
realizzazione, consumando così il vettore nel processo. Ecco perché non è possibile eseguire iterazioni su un vettore direttamente due volte: iterandolo su di esso la prima volta che lo consuma, dopo di che non esiste più.
Tuttavia, le sezioni sono diverse: una sezione è un puntatore immutabile, preso in prestito ai suoi dati; puntatori immutabili e presi in prestito possono essere copiati liberamente. Ciò significa che il IntoIterator
per le sezioni immutabili prende in prestito i dati e non li consuma (non che sia ). Oppure, per guardarlo in un altro modo, la sua implementazione IntoIterator
sta semplicemente prendendo una copia della sezione, mentre non è possibile copiare uno Vec
.
Va notato che si può iterare su una Vec
senza consumarlo entro l'iterazione di un prestito. Se controlli lo documentation for Vec
, noterai che elenca le implementazioni di IntoIterator
per Vec<T>
, &Vec<T>
e &mut Vec<T>
.
let mut a: Vec<i32> = vec![1, 2, 3];
for i in &a { // iterate immutably
let i: &i32 = i; // elements are immutable pointers
println!("{}", i);
}
for i in &mut a { // iterate mutably
let i: &mut i32 = i;// elements are mutable pointers
*i *= 2;
}
for i in a { // iterate by-value
let i: i32 = i; // elements are values
println!("{}", i);
}
// `a` no longer exists; it was consumed by the previous loop.
fonte
2016-01-03 02:50:08
pedantically, nel primo caso, il tipo di 'a' non è in realtà una fetta, è un riferimento ad un array di lunghezza 3. Tuttavia, * * coazioni Deref consentono un riferimento ad un array ad agire come una fetta nella maggior parte dei casi. – Shepmaster
@Shepmaster grazie per aver chiarito. Ho ragione nel pensare che il tipo di 'a' nel primo esempio è' &[i32; 3] ', mentre una porzione sarebbe' & [i32] '? Inoltre, la deref coercizione che hai menzionato è visibile in [la lista qui] (https://doc.rust-lang.org/std/ops/trait.Deref.html), o è più magico? –
Sì, quelli sarebbero i tipi. Ho mentito un po ', è un po' più magico di un dereferenziamento (https://github.com/rust-lang/rust/issues/29993), è una * coercizione *. I documenti verranno aggiornati presto con la correzione. – Shepmaster