Why can I iterate over a fragment twice, but not a vector?

If I try to iterate over a fragment twice, it will work fine :

let a = &[1, 2, 3]; for i in a { println!("{}", i); } for i in a { // works fine println!("{}", i); } 

If I try to iterate over a vector twice, a crash will occur :

 let a = vec![1, 2, 3]; for i in a { println!("{}", i); } for i in a { println!("{}", i); } 
 error[E0382]: use of moved value: 'a' --> src/main.rs:6:14 | 3 | for i in a { | - value moved here ... 6 | for i in a { | ^ value used here after move | = note: move occurs because 'a' has type 'std::vec::Vec<i32>', which does not implement the 'Copy' trait 

I see that the IntoIterator trait takes self by value, so it makes sense to me that the second example failed. Why is the first example successful?

+11
rust
source share
1 answer

As you said, for work, take the thing you asked for IntoIterator::into_iter and pass it through IntoIterator::into_iter to get the actual value of the iterator. Also, as you said, into_iter gets the topic by value.

Thus, when you try to Vector over Vector directly, this means that you will go through the entire vector, by value, into your IntoIterator implementation, thereby consuming the vector in this process. This is why you cannot iterate over a vector directly twice: iterate over it the first time it is consumed, after which it no longer exists.

However, slices differ: a slice is a constant, borrowed pointer to its data; immutable, borrowed pointers can be copied freely. This means that the IntoIterator for immutable fragments simply borrows the data and does not use it (not the way it could). Or, to look at it differently, its implementation of IntoIterator simply takes a copy of the slice, whereas you cannot copy Vec .

It should be noted that you can Vec over Vec without consuming it, sorting through a loan. If you check the documentation for Vec , you will notice that it lists the IntoIterator implementations for Vec<T> , &Vec<T> and &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. 
+19
source share

All Articles