Tak jak powiedziałeś, for
prace biorąc rzecz poprosiłeś go iteracyjne nad i przepuszczenie go przez IntoIterator::into_iter
produkować wartość iteratora rzeczywisty. Jak również powiedziałeś, into_iter
pobiera temat według wartości.
Tak, podczas próby iteracyjne nad Vector
bezpośrednio, to znaczy zdać cały wektor, wartością, do jego realizacji IntoIterator
, więc zużywa wektora w procesie. Dlatego nie można iterować nad wektorem bezpośrednio dwa razy: iteracja nad nim po raz pierwszy pochłania go, po czym już nie istnieje.
Jednak plasterki są różne: plasterek to niezmienny, pożyczony wskaźnik do danych; niezmienne, pożyczone wskaźniki mogą być swobodnie kopiowane. Oznacza to, że IntoIterator
dla niezmiennych plasterków po prostu pożycza dane i ich nie zużywa (nie, że może to być może być). Lub, patrząc na to w inny sposób, jego implementacja polega po prostu na skopiowaniu plasterka, podczas gdy nie można skopiować Vec
.
Należy zauważyć, że można iterować po wartości Vec
, nie używając, używając go do iteracji przez pożyczkę. Jeśli sprawdzisz numer documentation for Vec
, zauważysz, że zawiera on implementacje IntoIterator
dla Vec<T>
, &Vec<T>
i &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.
pedantycznie, w pierwszym przypadku, typ 'A' nie jest rzeczywiście kawałek, to odniesienie do tablicy o długości 3. Jednakże * coercions deref * umożliwiają odniesienie do tablicy działać jak kawałek w większości przypadków. – Shepmaster
@Shepmaster dzięki za wyjaśnienie. Czy mam rację, sądząc, że typem "a" w pierwszym przykładzie jest '&[i32; 3]', podczas gdy plasterek to '& [i32]'? Czy wymieniany przez Ciebie element deref jest widoczny na [liście] (https://doc.rust-lang.org/std/ops/trait.Deref.html), czy jest bardziej magiczny? –
Tak, to byłyby typy. Kłamałem trochę, jest to [nieco bardziej magiczne niż dereferencji] (https://github.com/rust-lang/rust/issues/29993), to * przymus *. Dokumenty zostaną wkrótce zaktualizowane wraz z poprawką. – Shepmaster