Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Rust Dictionary

  1. Home
  2. Rust Dictionary
  3. fn / Closures (|x| x+1)

fn / Closures (|x| x+1)

Functions in Rust are defined with the fn keyword. Closures are written in the form |args| expression and can capture variables from the surrounding scope. Closures can be passed as function arguments or assigned to variables.

Syntax

// A regular function definition. Parameter types and return type must be specified explicitly.
fn add(a: i32, b: i32) -> i32 {
    a + b  // The last expression is the return value (no semicolon).
}

// A closure (anonymous function). Types can be omitted thanks to type inference.
let add = |a, b| a + b;
let double = |x: i32| -> i32 { x * 2 };

// Capturing a variable from the outer scope (by borrow).
let offset = 10;
let add_offset = |x| x + offset;  // Borrows offset.

// move closure: takes ownership of captured variables.
let name = String::from("Rust");
let greet = move || println!("Hello, {}", name);  // Ownership of name is moved into the closure.

// A function that accepts a closure as an argument (using the Fn trait).
fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
    f(x)
}

Functions and Closures Reference

Syntax / TraitDescription
fn name(args) -> Type { }Defines a regular function.
|args| expressionDefines a closure (anonymous function). Types are inferred.
|args: Type| -> Type { }A closure with explicit type annotations.
move |args| expressionCaptures variables from the outer scope by moving their ownership.
Fn(&self)A closure that captures by immutable reference.
FnMut(&mut self)A closure that captures by mutable reference (can modify captured state).
FnOnce(self)A closure that takes ownership of captured variables (can only be called once).
fn(Type) -> TypeA function pointer type (distinct from closures).
impl Fn(Type) -> TypeUsed as the return type of a function that returns a closure.

Sample Code

// Higher-order function: accepts a function as an argument.
fn apply<F>(f: F, values: &[i32]) -> Vec<i32>
where
    F: Fn(i32) -> i32,
{
    values.iter().map(|&x| f(x)).collect()
}

// A function that returns a closure.
fn make_adder(n: i32) -> impl Fn(i32) -> i32 {
    move |x| x + n  // Moves ownership of n into the closure.
}

fn main() {
    // A regular function.
    fn square(x: i32) -> i32 {
        x * x
    }
    println!("square(5) = {}", square(5));

    // Basic closure usage.
    let double = |x| x * 2;
    let add_one = |x: i32| -> i32 { x + 1 };
    println!("double(4) = {}", double(4));
    println!("add_one(9) = {}", add_one(9));

    // Capturing a variable from the outer scope.
    let threshold = 5;
    let is_big = |x| x > threshold;  // Borrows threshold.
    println!("is_big(7) = {}", is_big(7));
    println!("is_big(3) = {}", is_big(3));

    // Passing a closure to a higher-order function.
    let nums = vec![1, 2, 3, 4, 5];
    let doubled = apply(|x| x * 2, &nums);
    println!("doubled: {:?}", doubled);

    let squared = apply(square, &nums);  // Regular functions can be passed too.
    println!("squared: {:?}", squared);

    // A function that returns a closure (closure factory).
    let add5 = make_adder(5);
    let add10 = make_adder(10);
    println!("add5(3) = {}", add5(3));
    println!("add10(3) = {}", add10(3));

    // FnMut: a closure that modifies its captured state.
    let mut counter = 0;
    let mut increment = || {
        counter += 1;
        counter
    };
    println!("count: {}", increment());  // 1
    println!("count: {}", increment());  // 2
    println!("count: {}", increment());  // 3
}

Overview

Rust closures automatically implement one of the Fn, FnMut, or FnOnce traits depending on how they capture variables from the surrounding scope. If a closure only reads captured variables, it implements Fn; if it modifies them, FnMut; if it takes ownership, FnOnce.

When passing a closure to another thread or a context that outlives the current scope, the move keyword is required. Using move transfers ownership of all captured variables into the closure.

While a closure holds a mutable reference to a captured variable, that variable cannot be used elsewhere at the same time. The borrow checker rules apply.

For detailed information on the closure traits (Fn / FnMut / FnOnce), see 'Fn / FnMut / FnOnce Traits'.

If you find any errors or copyright issues, please .