IntoIterator & Owned vs Borrowed
IntoIterator converts into iterator. Three modes: iter() shared borrow, iter_mut() mutable borrow, into_iter() owned consume.
Recipe
fn main() {
let v = vec![1, 2, 3];
for x in &v { print!("{x} "); }
for x in v.into_iter() { print!("{x} "); }
}When to reach for this: Choosing whether for moves, borrows, or mutates elements.
Working Example
fn total_borrowed(v: &Vec<i32>) -> i32 {
v.iter().sum()
}
fn total_owned(v: Vec<i32>) -> i32 {
v.into_iter().sum()
}
fn main() {
let data = vec![1, 2, 3];
println!("{} {}", total_borrowed(&data), data.len());
println!("{}", total_owned(data));
}What this demonstrates:
iterkeepsdatausable after suminto_iterconsumesdata- API signature documents ownership
Deep Dive
for x in collection calls into_iter on collection. &collection uses IntoIterator for &Vec yielding &T.
Arrays [T; N] implement IntoIterator copying elements if Copy.
Gotchas
- for x in vec moves vec - Cannot use after. Fix:
for x in &vec. - into_iter on &mut - Yields
&mut T. - Collect after into_iter - Source consumed.
- Iterator Item vs IntoIterator - Different associated types per impl.
- Generic fn + for - Use
impl IntoIteratoror genericI: IntoIterator.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Index loop | Need index + neighbors | Idiomatic for each |
drain | Remove subset | Full consume |
as_slice iteration | Explicit slice | iter() same |
FAQs
three forms table?
iter/&T, iter_mut/&mut T, into_iter/T owned.for moves?
for x in v moves if v not ref.IntoIterator bound?
fn f<I: IntoIterator<Item=T>>(i: I).array into_iter?
Moves elements if not Copy.str into_iter?
chars(), bytes(), lines().Option into_iter?
0 or 1 item.Result into_iter?
1 item Ok or Err as single element patterns rare.extend from iter?
vec.extend(iter).cloned()?
Iterator over clones of &T.copied()?
For Copy types from &T.Related
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.