Iterators
Just like C++, Rust uses iterators to provide a rich set of algorithms---and many crates such as IterTools
use this to build even more functionality.
For loops in Rust are iterators:
fn main() { // These are the same: let my_vec = vec![1,2,3,4]; for n in my_vec { println!("{n}"); } let my_vec = vec![1,2,3,4]; for n in my_vec.into_iter() { println!("{n}"); } }
These are also consuming iterators - they don't return a reference to the item in the collection, they move it into the loop scope and it is dropped at the end of the scope. You can't use my_vec
after iterating with a consuming iterator. To iterate references:
fn main() { // These are the same: let my_vec = vec![1,2,3,4]; for n in &my_vec { println!("{n}"); } //let my_vec = vec![1,2,3,4]; // No need to recreate the vector now for n in my_vec.iter() { println!("{n}"); } }
If you prefer a more iterator-based approach, you can also do the following:
fn main() { let my_vec = vec![1,2,3,4]; my_vec.iter().for_each(|n| println!("{n}")); // We pass in a closure }
This is equivalent to the C++:
#include <stdio.h>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4};
std::for_each(v.begin(), v.end(), [](int const& elem) {
printf("%d\n", elem);
});
return 0;
}
Iterators are frequently chained together (much like the new C++ Ranges system). For example:
fn main() { let my_vec = vec![1,2,3,4]; // Create a vector or strings let my_new_vec: Vec<String> = my_vec .iter() .map(|n| n.to_string()) // Map converts each entry to another type .collect(); let max = my_vec.iter().max(); let min = my_vec.iter().min(); let sum: u32 = my_vec.iter().sum(); let count = my_vec.iter().count(); let sum_with_fold = my_vec.iter().fold(0, |acc, x| acc + x); let all_the_numbers: Vec<(&u32, &String)> = my_vec.iter().zip(my_new_vec.iter()).collect(); println!("{all_the_numbers:?}"); my_vec .iter() .filter(|n| **n > 2) // Dereferencing because we have two layers of reference .for_each(|n| println!("{n}")); }
In other words, most of the algorithms in C++ are implemented. There's a lot more on the Rust documentation site: https://doc.rust-lang.org/std/iter/trait.Iterator.html#
We'll talk about parallel iteration later.