Giống như bạn nói, for
tác phẩm bằng cách lấy điều bạn hỏi nó để lặp qua, và đi qua nó thông qua IntoIterator::into_iter
để tạo ra giá trị iterator thực tế. Cũng như bạn đã nói, into_iter
lấy chủ đề theo giá trị.
Vì vậy, khi bạn cố gắng để lặp qua một Vector
trực tiếp, điều này có nghĩa là bạn vượt qua toàn bộ vector, bởi giá trị, thành thực hiện IntoIterator
của nó, do đó tiêu thụ vector trong quá trình này. Đó là lý do tại sao bạn không thể lặp qua một vectơ một cách trực tiếp hai lần: lặp lại nó lần đầu tiên tiêu thụ nó, sau đó nó không còn tồn tại nữa.
Tuy nhiên, các lát khác nhau: một lát là một con trỏ không thay đổi, được mượn tới dữ liệu của nó; không thể thay đổi, con trỏ mượn có thể được sao chép một cách tự do. Điều này có nghĩa rằng các IntoIterator
cho lát bất biến chỉ vay mượn dữ liệu và không tiêu thụ nó (không phải là nó có thể). Hoặc, để xem xét nó theo một cách khác, việc thực hiện IntoIterator
của nó chỉ đơn giản là lấy một bản sao của slice, trong khi bạn không thể sao chép Vec
.
Cần lưu ý rằng bạn có thể lặp qua một số Vec
mà không cần tiêu thụ nó bằng cách lặp lại qua một khoản vay. Nếu bạn kiểm tra documentation for Vec
, bạn sẽ lưu ý rằng danh sách triển khai IntoIterator
cho Vec<T>
, &Vec<T>
và &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.
Nguồn
2016-01-03 02:50:08
Về mặt lý thuyết, trong trường hợp đầu tiên, loại 'a' không thực sự là một phần, nó là tham chiếu đến một mảng có độ dài 3. Tuy nhiên, * deref coercions * cho phép tham chiếu đến mảng hoạt động giống như một lát trong hầu hết các trường hợp. – Shepmaster
@Shepmaster cảm ơn vì đã làm rõ. Tôi có nghĩ rằng kiểu 'a' trong ví dụ đầu tiên là '&[i32; 3]', trong khi một lát sẽ là' & [i32] '? Ngoài ra, là sự ép buộc deref bạn đã đề cập có thể nhìn thấy trong [danh sách ở đây] (https://doc.rust-lang.org/std/ops/trait.Deref.html), hoặc là nó huyền diệu hơn? –
Có, đó sẽ là các loại. Tôi đã nói dối một chút, nó là một chút huyền diệu hơn một sự dereference (https://github.com/rust-lang/rust/issues/29993), đó là một * cưỡng chế *. Các tài liệu sẽ được cập nhật sớm với bản sửa lỗi. – Shepmaster