Iterators in Rust

Iterators in Rust

Introduction

Iterators as the name says traverses over a sequence of elements by taking turns. In Rust Iterators doesn't do anything more, but you can always write logic to do more.

Example

This is how we can use iterators.

fn main() {
    let v = vec![1, 3, 5, 7];

    let v_iter = v.iter();

    for num in v_iter {
        println!("{num}");
    }
}

Output:

1
3
5
7

This is what we could do if we didn't use Iterators.

fn main() {
    let v = vec![1, 3, 5, 7];

    for i in 0..v.len() {
        let num = v[i];
        println!("{}", num);
    }
}

We have done this many times in many many languages. Very common. Simple stuff!

Iterator Trait

Now let's discuss about how Iterators work the way they work.

pub trait Iterator {
    type Item;

    fn next(&mut self) -> Option<Self::Item>;

    // methods...
}

So iterators have a trait Iterator, that has a type Item, and a function called next, that returns itself as an Option type. That is it may either return Some if an element exists or it'll return None (as discussed in the Option type Blog)

The Iterator trait also has a number of methods. You can find all of that in this link: https://doc.rust-lang.org/std/iter/trait.Iterator.html

Methods

fn main() {
    let v = vec![1, 3, 5, 7];

    let mut v_iter = v.iter();

    let sum: i32 = v_iter.sum();

    println!("{}", sum); // 16
}

This is how we can find the sum of elements in a Vector using iterators.

fn main() {
    let v1: Vec<i32> = vec![1, 3, 5, 7];

    let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();

    let v2_iter = v2.iter();

    for elem in v2_iter {
        print!("{elem} ");
    }
}

Output:

2 4 6 8

We can use the map method to perform operations on a Vector (using Closures) and store the result in another Vector using the collect method, all using Iterators.

fn main() {
    let v1: Vec<i32> = vec![1, 3, 4, 5, 6, 7, 10];

    let v2: Vec<_> = v1.iter().filter(|&x| x % 2 == 0).collect();

    let v2_iter = v2.iter();

    for elem in v2_iter {
        print!("{elem} ");
    }
}

Output:

4 6 10

Using the filter method to create a Vector of only the even numbers.

Conclusion

Iterators are an extremely important concept that we'll be using all the time from now on, in combination with closures. This is a part where Rust may feel somewhat like JavaScript! I did for me.

So that's all for now and, Cheers!