TL;DR

  • The iterator returned by into_iter may yield any of T, &T or &mut T, depending on the context.
  • The iterator returned by iter will yield &T, by convention.
  • The iterator returned by iter_mut will yield &mut T, by convention.

The first question is: "What is into_iter?"

into_iter comes from the IntoIterator trait:

pub trait IntoIterator 
where
    <Self::IntoIter as Iterator>::Item == Self::Item, 
{
    type Item;
    type IntoIter: Iterator;
    fn into_iter(self) -> Self::IntoIter;
}

You implement this trait when you want to specify how a particular type is to be converted into an iterator. Most notably, if a type implements IntoIterator it can be used in a for loop.

For example, Vec implements IntoIterator... thrice!

impl<T> IntoIterator for Vec<T>
impl<'a, T> IntoIterator for &'a Vec<T>
impl<'a, T> IntoIterator for &'a mut Vec<T>

Each variant is slightly different.

This one consumes the Vec and its iterator yields values (T directly):

impl<T> IntoIterator for Vec<T> {
    type Item = T;
    type IntoIter = IntoIter<T>;
 
    fn into_iter(mut self) -> IntoIter<T> { /* ... */ }
}

The other two take the vector by reference (don't be fooled by the signature of into_iter(self) because self is a reference in both cases) and their iterators will produce references to the elements inside Vec.

This one yields immutable references:

impl<'a, T> IntoIterator for &'a Vec<T> {
    type Item = &'a T;
    type IntoIter = slice::Iter<'a, T>;
 
    fn into_iter(self) -> slice::Iter<'a, T> { /* ... */ }
}

While this one yields mutable references:

impl<'a, T> IntoIterator for &'a mut Vec<T> {
    type Item = &'a mut T;
    type IntoIter = slice::IterMut<'a, T>;
 
    fn into_iter(self) -> slice::IterMut<'a, T> { /* ... */ }
}

So:

What is the difference between iter and into_iter?

into_iter is a generic method to obtain an iterator, whether this iterator yields values, immutable references or mutable references is context dependent and can sometimes be surprising.

iter and iter_mut are ad-hoc methods. Their return type is therefore independent of the context, and will conventionally be iterators yielding immutable references and mutable references, respectively.

ref: https://stackoverflow.com/a/34745885