Closures in Rust

Closures in Rust

Introduction

Closures are like functions but with more concise syntax.

Examples

Below code is how we write Closures.

fn main() {
    let add = |x, y| x + y;

    let result = add(3, 5);
    println!("Result: {}", result);
}

It gives us the sum of two numbers stored in add, that can also be reused like functions.

Doing the same with functions:

fn main() {
    let result = add(3, 5);
    println!("Result: {}", result);
}

fn add(a: i32, b: i32) -> i32 {
    a + b
}

Closures can be considered similar to arrow functions, or anonymous functions in JavaScript.

Below is how they're similar to functions from the Rust Book.

fn  add_one_v1   (x: u32) -> u32 { x + 1 }
let add_one_v2 = |x: u32| -> u32 { x + 1 };
let add_one_v3 = |x|             { x + 1 };
let add_one_v4 = |x|               x + 1  ;

Each of them does the same thing. But Closures don't necessarily need to have types because the return value is stored in a variable (not a variable, more like an anonymous or arrow function) then and there, unlike functions. We can leave it up to the compiler to infer.

But one thing to note is, the types must be consistent. We cannot do something like this:

fn main() {
    let clsr = |x| x;

    let a = clsr(5);
    let b = clsr(5.5);

    println!("{a}");
    println!("{b}");
}

Error:

error[E0308]: mismatched types
 --> src/main.rs:5:18
  |
5 |     let b = clsr(5.5);
  |             ---- ^^^ expected integer, found floating-point number
  |             |
  |             arguments to this function are incorrect
  |
note: expected because the closure was earlier called with an argument of type `{integer}`
 --> src/main.rs:4:18
  |
4 |     let a = clsr(5);
  |             ---- ^ expected because this argument is of type `{integer}`
  |             |
  |             in this closure call
note: closure parameter defined here
 --> src/main.rs:2:17
  |
2 |     let clsr = |x| x;
  |                 ^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `closure_types` (bin "closure_types") due to previous error

If we're passing integers, the type will be infered by the compiler, and it's fixed. We cannot pass a float or any other type later.

Conclusion

That's all about the basics of Closures. Cheers!