What is the difference between iter and into_iter?

ghz 7months ago ⋅ 105 views

I am doing the Rust by Example tutorial, which has this code snippet:

// Vec example
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];

// `iter()` for vecs yields `&i32`. Destructure to `i32`.
println!("2 in vec1: {}", vec1.iter()     .any(|&x| x == 2));
// `into_iter()` for vecs yields `i32`. No destructuring required.
println!("2 in vec2: {}", vec2.into_iter().any(| x| x == 2));

// Array example
let array1 = [1, 2, 3];
let array2 = [4, 5, 6];

// `iter()` for arrays yields `&i32`.
println!("2 in array1: {}", array1.iter()     .any(|&x| x == 2));
// `into_iter()` for arrays unusually yields `&i32`.
println!("2 in array2: {}", array2.into_iter().any(|&x| x == 2));

I am quite confused — for a Vec, the iterator returned from .iter yields references and the iterator returned from .into_iter yields values, but for an array these iterators are identical?

What is the use case/API for these two methods?

Answers

The iter() and into_iter() methods serve different purposes depending on the type of collection they are called on.

  1. For Vec<T>:

    • iter(): Returns an iterator over references to the elements of the vector (&T). This allows you to iterate over the vector without consuming it.
    • into_iter(): Consumes the vector and returns an iterator that takes ownership of the elements, yielding them by value (T). This allows you to iterate over the vector while transferring ownership of its elements.

    Use iter() when you want to iterate over the elements of the vector without modifying or consuming it. Use into_iter() when you want to consume the vector and iterate over its elements, potentially transferring ownership to the iterator.

  2. For arrays ([T; N]):

    • Both iter() and into_iter() return iterators over references to the elements of the array (&T).

    In the case of arrays, since they have a fixed size and elements are stored contiguously in memory, there's no difference between the two iterators. Both iter() and into_iter() produce iterators that yield references to the elements of the array.

    So, for arrays, you can use either iter() or into_iter() based on your preference or convenience, as they provide the same functionality of iterating over the elements of the array by reference.

In summary, the difference between iter() and into_iter() is more pronounced for Vec<T> where ownership semantics are involved, while for arrays both methods behave similarly as they yield references to the array's elements.