Iterators
into_iter()
The .into_iter() method, defined by the IntoIterator trait, consumes its receiver by value (self) and converts it into an Iterator.
Context-Dependent Behavior of .into_iter()
Because IntoIterator is implemented separately for owned collections (T), shared references (&T), and mutable references (&mut T), what .into_iter() yields depends on the receiver type it is called on:
| Receiver Expression | Receiver Type | Item Yielded by .into_iter() |
Equivalent Method |
|---|---|---|---|
vec.into_iter() |
Vec<T> (owned) |
T (moves each element out and drops the Vec buffer) |
Owned consumption |
(&vec).into_iter() |
&Vec<T> |
&T |
vec.iter() |
(&mut vec).into_iter() |
&mut Vec<T> |
&mut T |
vec.iter_mut() |
Moving Owned Elements Out of a Collection
Calling .into_iter() on an owned Vec<T>, [T; N], HashSet<T>, or HashMap<K, V> transfers ownership of every element out of the collection without cloning:
fn main() {
let messages = vec![
String::from("init"),
String::from("ready"),
String::from("shutdown"),
];
// Moves each `String` out of `messages` and appends "!" in place:
let shouting: Vec<String> = messages
.into_iter()
.map(|mut msg| {
msg.push('!');
msg.to_uppercase()
})
.collect();
println!("{shouting:?}");
}
["INIT!", "READY!", "SHUTDOWN!"]
Once messages.into_iter() is called, messages has been moved and cannot be accessed again (E0382):
// ❌ does not compile
fn main() {
let names = vec![String::from("Alice"), String::from("Bob")];
let _iter = names.into_iter();
println!("{names:?}");
}
error[E0382]: borrow of moved value: `names`
--> src/main.rs:5:15
|
3 | let names = vec![String::from("Alice"), String::from("Bob")];
| ----- move occurs because `names` has type `Vec<String>`, which does not implement the `Copy` trait
4 | let _iter = names.into_iter();
| ----------- `names` moved due to this method call
5 | println!("{names:?}");
| ^^^^^^^ value borrowed here after move
|
help: consider calling `.iter()` instead of `.into_iter()` to borrow `names`
Fixed-Size Array .into_iter() (Rust 2021 and 2024 Editions)
Fixed-size arrays [T; N] implement IntoIterator<Item = T> by value, so calling [a, b, c].into_iter() yields owned T elements directly:
fn main() {
let arr = [String::from("one"), String::from("two")];
for word in arr.into_iter() {
// `word` is an owned `String`, not `&String`
println!("Owned word: {word}");
}
}
Owned word: one
Owned word: two