Difference Between into_iter, iter() and iter_mut() in rust

In Rust, into_iter(), iter(), and iter_mut() are methods provided by the Iterator trait, and they are used to create iterators over collections. Here's a breakdown of the differences between them:
into_iter()Ownership: Transfers ownership of the original collection to the iterator.
Mutability: The original collection cannot be used after calling
into_iter()because ownership has been transferred.Example:
let vec = vec![1, 2, 3]; let iter = vec.into_iter(); for num in iter { // Ownership has been transferred, vec cannot be used here. println!("{}", num); }#[test] fn into_iter_demo() { let v1 = vec![1, 2, 3]; let mut v1_iter = v1.into_iter(); // into_iter() returns an iterator from a value. assert_eq!(v1_iter.next(), Some(1)); assert_eq!(v1_iter.next(), Some(2)); assert_eq!(v1_iter.next(), Some(3)); assert_eq!(v1_iter.next(), None); }
iter()Ownership: Borrows the elements of the collection immutably.
Mutability: The original collection remains accessible for read-only operations.
Example:
let vec = vec![1, 2, 3]; let iter = vec.iter(); for &num in iter { // The original vec is still accessible for read-only operations. println!("{}", num); }#[test] fn iter_demo() { let v1 = vec![1, 2, 3]; let mut v1_iter = v1.iter(); // iter() returns an iterator of slices. assert_eq!(v1_iter.next(), Some(&1)); assert_eq!(v1_iter.next(), Some(&2)); assert_eq!(v1_iter.next(), Some(&3)); assert_eq!(v1_iter.next(), None); }
iter_mut()Ownership: Borrows the elements of the collection mutably.
Mutability: Allows modifying the original collection through mutable references.
Example:
let mut vec = vec![1, 2, 3]; let iter_mut = vec.iter_mut(); for num in iter_mut { // The original vec can be modified through mutable references. *num += 1; } println!("{:?}", vec); // Output: [2, 3, 4]#[test] fn iter_mut_demo() { let mut v1 = vec![1, 2, 3]; let mut v1_iter = v1.iter_mut(); // iter_mut() returns an iterator that allows modifying each value. assert_eq!(v1_iter.next(), Some(&mut 1)); assert_eq!(v1_iter.next(), Some(&mut 2)); assert_eq!(v1_iter.next(), Some(&mut 3)); assert_eq!(v1_iter.next(), None); }
When to use into_iter, iter and iter_mut?
into_iter():When Ownership Transfer is Acceptable: Use
into_iter()when you are okay with transferring ownership of the original collection to the iterator.For Consuming the Collection: If you don't need the original collection after creating the iterator and plan to consume its elements,
into_iter()is a good choice.iter():For Read-Only Access: Use
iter()when you need read-only access to the elements of the collection without transferring ownership.When You Need to Keep the Original Collection: If you need the original collection for further use after creating the iterator,
iter()is suitable.
iter_mut():For Mutable Access: Use
iter_mut()when you need mutable access to the elements of the collection, allowing you to modify them.When You Need to Modify the Original Collection: If you need to modify the elements of the original collection, use
iter_mut()to obtain mutable references.
Conclusion:
In Rust, the methods into_iter(), iter(), and iter_mut() are used to create iterators over collections. into_iter() transfers ownership of the collection, iter() borrows the elements immutably, and iter_mut() borrows them mutably. These methods are used based on whether ownership transfer, read-only access, or mutable access to the elements is required.