Best explanation of closure in Rust

Omar Faroque
Coding Rust
Published in
5 min readAug 28, 2020

--

So far, we’ve made lots of functions in Rust, but we’ve given them all names. Rust also allows us to create anonymous functions. Rust’s anonymous functions are called closures. By themselves, closures aren’t all that interesting, but when you combine them with functions that take closures as arguments, really powerful things are possible.

Let’s make a closure:

let add_one = |x| { 1 + x };println!("The sum of 5 plus 1 is {}.", add_one(5));

We create a closure using the |...| { ... } syntax, and then we create a binding so we can use it later. Note that we call the function using the binding name and two parentheses, just like we would for a named function.

Let’s compare syntax. The two are pretty close:

let add_one = |x: i32| -> i32 { 1 + x };
fn add_one (x: i32) -> i32 { 1 + x }

As you may have noticed, closures infer their argument and return types, so you don’t need to declare one. This is different from named functions, which default to returning unit (()).

There’s one big difference between a closure and named functions, and it’s in the name: a closure “closes over its environment.” What does that mean? It means this:

fn main() {
let x: i32 = 5;
let printer = || { println!("x is: {}", x); }; printer(); // prints "x is: 5"
}

--

--