# Why does into_iter() not return type T?

From this topic, I guess `Vec<i32>.into_iter()` would return `i32` type.
https://doc.rust-lang.org/std/iter/index.html#the-three-forms-of-iteration

• `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.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a0ae390e8dca9d5b8183842c82194210

``````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() {}
``````
1 Like

Each of `Vec<T>`, `&Vec<T>`, and `&mut Vec<T>` has its own `IntoIterator` implementation, returning `T`, `&T`, and `&mut T` respectively.

6 Likes

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.

2 Likes

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
}``````
7 Likes