From this topic, I guess Vec<i32>.into_iter() would return i32 type.
iter() , which iterates over &T .
iter_mut() , which iterates over &mut T .
into_iter() , which iterates over T .
But as following, I find that into_iter() depend on the context , and iter(), iter_mut() work fine.
fn into_iter_mut(v: &mut Vec<i32>) {
for i in v.into_iter(){
// expected `i32`, found `&mut i32`
let a:i32 = i;
}
for i in v.iter(){
// expected `i32`, found `&i32`
let a:i32 = i;
}
for i in v.iter_mut(){
// expected `i32`, found `&mut i32`
let a:i32 = i;
}
}
fn into_iter_ref(v: &Vec<i32>) {
for i in v.into_iter(){
// expected `i32`, found `&i32`
let a:i32 = i;
}
for i in v.iter(){
// expected `i32`, found `&i32`
let a:i32 = i;
}
for i in v.iter_mut(){
// expected `i32`, found `&mut i32`
let a:i32 = i;
}
}
fn into_iter(v: Vec<i32>) {
for i in v.into_iter(){
// expected `i32`, found `i32`
let a:i32 = i;
}
for i in v.iter(){
// expected `i32`, found `&i32`
let a:i32 = i;
}
for i in v.iter_mut(){
// expected `i32`, found `&mut i32`
let a:i32 = i;
}
}
fn main() {}
And indeed you couldn't call Vec's own IntoIterator through a reference even by manually dereferencing it, because you cannot consume (move) what you're only borrowing. And consuming self is the true defining semantic of IntoIterator; if you just want copies or clones of the elements, that can be done for any iterator using the copied() and cloned() adapters respectively.
Well, it is possible to move out of something behind a mutably reference, you just also have to move something else in at the same time using mem::swap or mem::replace or mem::take. E.g.
fn into_iter_mut(v: &mut Vec<i32>) {
for i in std::mem::take(v).into_iter() {
// compiles fine
let a: i32 = i;
}
}
@z-Wind
In this case, thereβs also the alternative of using Vec::drain (so: βfor i in v.drain(..) {β) that keeps the allocation in place, or in the specific case of i32, you can use for i in v.iter().copied() even with the immutable reference. Also note that having functions with &Vec<i32>-arguments, i.e. shared reference to Vec, is an antipattern in general, youβd usually want to change that to &[i32] instead. Finally note that into_iter() is often redundant when for loops are used, since
for i in ππ₯ππ {β¦}
desugars to something similar to
let iterator = ππ₯ππ.into_iter();
while let Some(i) = iterator.next() {β¦}
This β together with the IntoIter implementations that @2e71828 mentioned β allows for nice for loops without any need for explicit iter or iter_mut calls like this:
let v = vec![1,2,3];
for i in &v {
// i: &i32
}
for i in &mut v {
// i: &mut i32
}
for i in v { // <- consumes / moves out of `v`
// i: i32
}