Closures in Rust

Rust supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

fn main() {
    // This function `int_seq` returns another function, which
    // we define anonymously in the body of `int_seq`. The
    // returned function closes over the variable `i` to
    // form a closure.
    fn int_seq() -> impl Fn() -> i32 {
        let mut i = 0;
        move || {
            i += 1;
            i
        }
    }

    // We call `int_seq`, assigning the result (a function)
    // to `next_int`. This function value captures its
    // own `i` value, which will be updated each time
    // we call `next_int`.
    let mut next_int = int_seq();

    // See the effect of the closure by calling `next_int`
    // a few times.
    println!("{}", next_int());
    println!("{}", next_int());
    println!("{}", next_int());

    // To confirm that the state is unique to that
    // particular function, create and test a new one.
    let mut new_ints = int_seq();
    println!("{}", new_ints());
}

To run the program:

$ cargo run
1
2
3
1

In this Rust example, we’ve created a closure that increments and returns a counter. The int_seq function returns a closure that captures a mutable i variable. Each time the closure is called, it increments i and returns the new value.

The impl Fn() -> i32 in the return type of int_seq indicates that it returns some type that implements the Fn() -> i32 trait, which is our closure.

We create two separate counters (next_int and new_ints) to demonstrate that each closure maintains its own independent state.

This example showcases Rust’s powerful closure system, which allows for elegant and efficient use of anonymous functions with captured state.

The last feature of functions we’ll look at for now is recursion.