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.