← Back to Rust Course | Chapter 4: Functions | Lesson 4 of 6

Closures Basics

A closure is a small, portable function you can create on the spot that remembers things from around where it was written.

Defining a Closure

A closure is written using pipes | | around its parameter list, followed by an expression or block. Closures can be stored in a variable and then called just like a function.

Example: Defining a Closure

markup
fn main() {
    let add_one = |x: i32| x + 1;
    println!("{}", add_one(5));
}

Capturing Variables from the Environment

Unlike regular functions, closures can directly use variables from the scope where they were defined, without needing to receive them as parameters.

Example: Capturing Variables from the Environment

markup
fn main() {
    let multiplier = 3;
    let multiply = |x: i32| x * multiplier;
    println!("{}", multiply(7));
}

Type Inference in Closures

Closures typically don't need explicit parameter or return types annotated -- Rust infers them from how the closure is used, keeping closure syntax compact.

Example: Type Inference in Closures

markup
fn main() {
    let square = |x| x * x;
    let result: i32 = square(6);
    println!("{}", result);
}

Multi-line Closure Bodies

When a closure needs more than one expression, its body can be a full block in curly braces, just like a function body.

Example: Multi-line Closure Bodies

markup
fn main() {
    let describe = |n: i32| {
        let kind = if n % 2 == 0 { "even" } else { "odd" };
        format!("{} is {}", n, kind)
    };
    println!("{}", describe(9));
}
Common Mistakes
  1. Forgetting closures can capture variables from their surrounding scope automatically, unlike regular fn functions.
  2. Writing unnecessary type annotations on every closure parameter, when Rust can usually infer them from usage.
  3. Confusing closure syntax |x| x + 1 with a bitwise OR expression when reading unfamiliar code.
Chapter Summary
  • Closures are anonymous functions written with pipes around parameters, like |x| x + 1.
  • Closures can capture variables from the environment they were defined in.
  • Closure parameter and return types are usually inferred, unlike regular function definitions.
  • Closures can be stored in variables and passed around like values.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.