The difference lies in ownership and mutability: iter() borrows immutably, iter_mut() borrows mutably, and into_iter() takes ownership.
let v = vec![1, 2, 3];
// Immutable borrow: reads values, keeps v usable
for x in v.iter() { println!("{}", x); }
// Mutable borrow: modifies values, keeps v usable
for x in v.iter_mut() { *x += 1; }
// Takes ownership: consumes v, returns owned values
for x in v.into_iter() { println!("{}", x); }