# Closure: Lambda Functions of Rust

A **closure** is an anonymous function that can capture variables from its environment. At a high level, Rust closures allow you to write small, concise functions inline, without having to formally define a new `fn` with a name. They’re particularly handy when you want to pass a piece of functionality around, such as to iterators or threads.

Capturing **variables from its enclosing scope** means you don’t have to manually pass those variables as parameters; the compiler implicitly makes them accessible inside the closure.

```rust
let x = 10;
// `double_x` is a closure that captures `x` from the environment
let double_x = || x * 2;
```

## Closure Syntax

Parameters in pipes (`|`)

```rust
let closure = |param1, param2| {
    // body
};
```

**Optional curly braces** if the body is a single expression:

```rust
let closure = |x| x + 1;
```

Often, you don't have to specify types for the parameters, but if you'd like to be clear, you certainly can.

```rust
let add = |a, b| a + b;
let add = |a: i32, b: i32| -> i32 { a + b };
```

## Capturing Variables

Unlike standard functions, closures have a special talent for capturing variables from the scope where they are created. Rust closures can capture:

1. **By reference** (`&T`)
    
2. **By mutable reference** (`&mut T`)
    
3. **By value / move** (`T`)
    

### How Rust Decides the Capture Method

Rust uses **capture inference** to figure out the best way to capture each variable. It decides this based on how the closure *uses* the variable:

1. **If the closure just needs to read the variable**, it will capture it by **immutable reference**.
    
2. **If the closure needs to change the variable**, it will capture it by **mutable reference**.
    
3. **If the closure needs to take full ownership of the variable** (like when it moves it or keeps it somewhere that lasts longer than the current scope), it will capture it by **value** (ownership).
    

```rust
fn main() {
    let mut s = String::from("hello");
    let print_s = || println!("{}", s); // 1) Capture by reference
    
    print_s(); // Prints "hello"
    // This closure modifies `s`, so it captures `s` by &mut.
    let mut append_exclamation = || {    // 2) Capture by mutable reference
        s.push('!');
    };
    
    append_exclamation();
    println!("{}", s); // "hello!"

    // 3) Capture by value (move) Using move explicitly forces ownership capture.
    let take_ownership = move || {
        println!("Moved: {}", s);
    }; 
    take_ownership();
}
```

Lets try to print s after running take\_ownerhship closure

```rust
println!("{}", s); 

error[E0382]: borrow of moved value: `s`
  --> src/main.rs:20:20
   |
2  |     let mut s = String::from("hello");
   |         ----- move occurs because `s` has type `String`, which does not implement the `Copy` trait
...
15 |     let take_ownership = move || {
   |                          ------- value moved into closure here
16 |         // We won't be able to use `s` after this closure is created if it truly takes it by value.
17 |         println!("Moved: {}", s);
   |                               - variable moved due to use in closure
...
20 |     println!("{}", s); // Error: `s` was moved
   |                    ^ value borrowed here after move
```

## The `move` Keyword

By default, the compiler uses the least restrictive capture mode it can. But if you want to change that, you can use `move`. This makes sure **all** captures in that closure take ownership, using move semantics.

## Closure Traits: `Fn`, `FnMut`, and `FnOnce`

Closures can implement one or more of these **function traits**, based on how they capture their environment:

`Fn`: A closure that only needs an **immutable reference** to its environment.

`FnMut`: A closure that only needs a **mutable reference** to its environment.

`FnOnce`: A closure that can be called **at least once**. It may consume (move) variables it captures, so it can only be called once if it moves.

Conceptually, you can think of them as:

* `FnOnce`: uses `self`
    
* `FnMut`: uses `&mut self`
    
* `Fn`: uses `&self`
    

Let do a bit of deep dive on these traits.

## `Fn` trait

As described in Rust documentation, `Fn` is the trait for *function-like* types that can be **called repeatedly** without needing to change anything in their environment. Put simply, if a piece of code can be **called multiple times** and doesn’t need to **mutate** (change) any variables it has captured, it usually implements `Fn`. *This trait (*`Fn`) should not be confused with [function pointers](https://doc.rust-lang.org/std/primitive.fn.html) (`fn`).

### `Fn` vs. `fn` (Function Pointers)

* `fn` (lowercase) refers to a **function pointer** type. For example, `fn(i32) -> i32` is a pointer to a function that takes an `i32` and returns an `i32`.
    
* `Fn` (uppercase) is a **trait**, which can be implemented by *any* callable type, such as:
    
    * **Closures** (anonymous functions that capture variables),
        
    * **Function pointers** (`fn(...)`) themselves,
        
    * or even your own custom types that implement the `Fn` trait.
        

To illustrate, consider a function that takes an integer as input and returns its square. In Rust, a **function pointer** has the type `fn(…) -> …`. For example, here is a simple function that squares an integer:

```rust
fn square(x: i32) -> i32 {
    x * x
}
```

We can create a function that **accepts** a function pointer of this type. `apply_square` takes a parameter `f: fn(i32) -> i32`. This means the caller needs to pass a **pointer to a function** with that exact signature (no captures, no closures). We can pass `square` (a regular function) to it, and it works perfectly.

```rust
// Accepts a function pointer "fn(i32) -> i32".
fn apply_square(f: fn(i32) -> i32, value: i32) -> i32 {
    f(value)
}

fn main() {
    let result = apply_square(square, 4);
    println!("Result using function pointer: {}", result); 
}
```

If we try to pass a **closure** instead of a function pointer, you may expect a compilation error or warning.

```rust
let closure = |x: i32| x * x;
let result = apply_square(closure, 4);
```

Wait, it worked perfectly as well and we know **Closures** in Rust are **not** the same type as `fn(…) -> …`.

In this case, a **closure** **does not capture anything** from its environment (i.e., it doesn’t use any local variables from the enclosing scope) is effectively equivalent to a plain function. Rust can **coerce** (convert) that closure into a **function pointer**. This is a **special-case automatic conversion** allowed by the compiler.

Lets capture some variable from its environment.

```rust
let x = 4;
let closure = || x * x;
let result = apply_square(closure, x);

error[E0308]: mismatched types
  --> src/main.rs:24:40
   |
22 |     let closure = || x * x;
   |                   -- the found closure
23 |     
24 |     let result = apply_square(closure, x);
   |                  --------------------- ^^^^^^^ expected fn pointer, found closure
   |                  |
   |                  arguments to this function are incorrect
   |
   = note: expected fn pointer `fn(i32) -> i32`
                 found closure `{closure@src/main.rs:22:19: 22:21}`
note: closures can only be coerced to `fn` types if they do not capture any variables
  --> src/main.rs:22:22
   |
22 |     let closure = || x * x;
   |                      ^ `x` captured here
note: function defined here
  --> src/main.rs:7:4
```

To allow a capturing closure to pass, you need to use a **trait bound** like Fn

```rust
fn apply_square_fn<F>(f: F) -> i32
where
    F: Fn() -> i32,
{
    f()
}
let x = 4;
let closure = || x * x;
let result = apply_square_fn(closure);
```

The main thing to remember is that `fn(i32) -> i32` is a *function pointer type*. It's only for real functions or some non-capturing closures that can be turned into a `fn` pointer. If you set your parameter as a function pointer type, you **can't** pass a capturing closure. It **does not** capture any state.

## `FnMut` Trait

A closure that only needs a **mutable reference** to its environment. It can be called repeatedly, but it might mutate captured variables. `FnMut` is implemented automatically by closures which take mutable references to captured variables, as well as all types that implement [`Fn`](https://doc.rust-lang.org/std/ops/trait.Fn.html). Any `FnMut` is automatically also an `FnOnce`, because if you can call something multiple times, you can at least call it once.

In the below example, the closure **changes** `count`. Therefore, it needs a **mutable borrow** of `count`. That means it implements at least `FnMut`.

```rust
let mut count = 0;
// This closure captures `count` by mutable reference,
let mut increment = || { count += 1  }; // compiler infers `increment: FnMut() -> ()`.
    
increment(); //"count: 1"
increment(); //"count: 2"
println!("Final count: {}", count); // 2
```

### Using `FnMut` as a Trait Bound

Often, you’ll write **generic functions** that accept any closure (or function) with certain capabilities. If your function needs to *call a closure multiple times* and *allow it to mutate captured state*, you should use an `FnMut` bound.

```rust
// It requires that `f` can be called multiple times AND can mutate state.
fn call_multiple_times<F>(mut f: F, times: usize)
where
    F: FnMut(),
{
    for _ in 0..times {
        f();
    }
}

fn main() {
    let mut counter = 0;
    
    let mut increment = || {
        counter += 1;
        println!("counter: {}", counter);
    };
    // The closure implements `FnMut`, so it's valid here.
    call_multiple_times(increment, 3);
    // Output:
    // counter: 1
    // counter: 2
    // counter: 3

    println!("Final counter: {}", counter); // 3
}
```

`FnMut` is the trait for callables that may mutate captured state and can be called multiple times.

## `FnOnce` Trait

A closure that can be called **at least once**. It may consume (move) variables it captures, so it can only be called once if it moves something out of the environment. Every closure implements `FnOnce` because, at the bare minimum, you can call it once.

In simple terms, **if a closure takes ownership of data from its environment, it's at least** `FnOnce`. It could also be `FnMut` or `Fn`, based on whether it changes or just reads that data.

> Every closure implements at least one of these traits, and sometimes more, depending on how it handles variables.

Essentially:

> FnOnce &lt;= FnMut &lt;= Fn

(`FnOnce` is the “weakest” requirement; `Fn` is the “strongest”)

## Manually Implementing `Fn`

In most real-world Rust code, you **do not** manually implement `Fn`, because **closures and function pointers** automatically implement it. However, if you want a custom **struct** to behave like a function, you need to implement `Fn`, `FnMut`, and `FnOnce` by hand.

**Important**: This is only possible with **nightly Rust**, using special features. You can manually implement `Fn`, `FnMut`, or `FnOnce` by enabling `unboxed_closures` and `fn_traits`, using the `extern "rust-call"` syntax.

Below is a **nightly-only** example. It shows a `struct MultiplyBy` that holds a multiplier. We implement all three traits so that it can be called like a function.

```rust
#![feature(fn_traits)]
#![feature(unboxed_closures)]
use std::ops::{Fn, FnMut, FnOnce};

struct MultiplyBy(i32); // A struct that holds a multiplier.

//1) Implement FnOnce for MultiplyBy. Notice the signature uses `call_once(self, (arg,): (i32,))`.
impl FnOnce<(i32,)> for MultiplyBy {
    type Output = i32;

    extern "rust-call" fn call_once(self, (arg,): (i32,)) -> Self::Output {
        self.0 * arg
    }
}
//2)Implement FnMut for MultiplyBy. This time the method is `call_mut(&mut self, (arg,): (i32,))`.
impl FnMut<(i32,)> for MultiplyBy {
    extern "rust-call" fn call_mut(&mut self, (arg,): (i32,)) -> Self::Output {
        self.0 * arg
    }
}
// 3) Finally, implement Fn for MultiplyB. Now we use `&self`.
impl Fn<(i32,)> for MultiplyBy {
    extern "rust-call" fn call(&self, (arg,): (i32,)) -> Self::Output {
        self.0 * arg
    }
}
fn main() {
    let multiply_by_10 = MultiplyBy(10);
    // Because we've implemented Fn, we can call our struct like a function:
    println!("{}", multiply_by_10(5));  // 50
    println!("{}", multiply_by_10(12)); // 120
}
```

**Why implement all three?**  
In Rust, `Fn` is a *supertrait* of `FnMut`, which is a *supertrait* of `FnOnce`. So you need to implement them in ascending order if you want a type to fully behave like a closure that can be called multiple times without mutation.

* `FnOnce` says “I can be called *once*.”
    
* `FnMut` says “I can be called multiple times, mutably.”
    
* `Fn` says “I can be called multiple times, immutably.”
    

## Under the hood: Anonymous Struct Holding Captures

When you write a closure, Rust will **create** a hidden struct (let’s call it the **closure object**) that:

1. **Has fields** for each variable it captures.
    
2. **Implements** one or more of the `FnOnce`, `FnMut`, and/or `Fn` traits.
    
3. **Implements** a “call” method (i.e. `call`, `call_mut`, or `call_once`) that executes the closure body, referencing or consuming those fields as needed.
    

Compiler generates this struct with name something like `closure@ID`.

```rust
fn main() {
    let mut count = 0;
    let mut increment = || {
        count += 1;
        println!("count: {}", count);
    };

    increment();
    increment();
}
```

Conceptually, Rust might generate a struct like:

```rust
struct Closure_CountMut<'a> {
    count_ref: &'a mut i32,
}

// This closure implements FnMut, because it mutates its captures.
impl<'a> FnMut(()) for Closure_CountMut<'a> {
    extern "rust-call" fn call_mut(&mut self, _args: ()) {
        *self.count_ref += 1;
        println!("count: {}", *self.count_ref);
    }
}

fn main() {
    let mut count = 0;
    // The closure is constructed
    let mut increment = Closure_CountMut {
        count_ref: &mut count,
    };

    // When we call it, it calls `call_mut`
    increment.call_mut(());
    increment.call_mut(());
}
```

You can say that closure is **syntactic sugar** for an **anonymous struct** that holds the captured variables.

This is all done **automatically** by the compiler, but understanding this model helps clarify why closures have their particular capturing rules and trait bounds.

## Summary

In summary, I would say if you need a small piece of logic that depends on local variables, but you don’t want to define a whole new named function. That’s exactly where **closures** come in. A closure is essentially an **anonymous function** that **automatically captures** variables from the scope in which it’s defined. Sometimes it merely borrows these variables (immutably or mutably), and other times it takes full ownership—Rust decides which strategy to use based on how you interact with those variables.

Once created, the closure acts like a callable object, implementing one or more of the function traits—`Fn`, `FnMut`, or `FnOnce`—depending on whether it only reads, mutates, or consumes its captured data. In cases where a closure doesn’t capture anything at all, the compiler can even **coerce** it into a plain function pointer.

Under the hood, Rust constructs an **anonymous struct** to hold whatever variables the closure captures, then it implements the relevant trait methods for that struct. Most of the time, these traits are derived automatically by the compiler.

Ultimately, this allows you to write concise, powerful inline functions that interact seamlessly with their surrounding environment—without ever losing track of Rust’s safety and performance guarantees. When it comes to performance, the use of closures in Rust is truly remarkable. Closures are designed to be efficient and fast, allowing you to write code that executes quickly without sacrificing safety or functionality. The Rust compiler is highly optimized for closures.
