SoFunction
Updated on 2025-04-07

Anonymous function of closure capture environment in Rust

1. Definition and use of closures

The basic syntax of closure is as follows:

let closure = |Parameter list| expression;

For example, define a closure that takes an integer and returns its square:

let square = |x: i32| x * x;

You can call closures like calling a function:

let result = square(5);
println!("5 The square is {}", result);

2. Capture variables in the environment

An important feature of closures is the ability to capture variables in their defined environment. Depending on the capture method, closures can be divided into three types:FnOnceFnMutandFn

2.1 FnOnce: Obtain ownership

If the closure takes ownership of the environment variable, it can only be called once. For example:

let s = String::from("hello");
let consume = move || {
    println!("{}", s);
    // The ownership of s has been moved to the closure and cannot be used later};
consume();
// println!("{}", s); // Compilation error:s Ownership of the

In the above code,moveKeyword forced closure acquisitionsownership ofsNo longer available outside the closure.

2.2 FnMut: Variable Borrow

If the closure captures environment variables in a mutable borrowed way, it can modify these variables. For example:

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

Each callincrementWhen closure,countThe values ​​of each are increased by 1.

2.3 Fn: Immutable borrowing

If the closure captures environment variables in an immutable borrowed way, it can only read these variables and cannot modify them. For example:

let x = 5;
let print_x = || {
    println!("x: {}", x);
};
print_x();

In this example,print_xClosures can only be readxThe value of , cannot be modified.

3. Type inference and annotation of closures

The Rust compiler will automatically infer the type of closure based on the usage of environment variables in the closure body. Normally, explicit annotations are not required. However, in some cases, it may be necessary to specify the type of closure explicitly:

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

In this example,add_oneIt's an acceptancei32Type parameter and returni32Closure of type result.

4. Comparison of closures and functions

Although both closures and functions can accept parameters and return values, closures have the following unique features:

  • Capture the environment: A closure can capture variables in its definition environment, but a function cannot.
  • Type inference: The type of the closure can be automatically inferred by the compiler, while the parameter and return value types of the function need to be explicitly declared.

5. Practical application of closures

Closures are widely used in Rust, especially in scenarios related to iterators and concurrent programming. For example, use closures to filter a collection:

let numbers = vec![1, 2, 3, 4, 5];
let even_numbers: Vec<i32> = numbers.into_iter()
    .filter(|&x| x % 2 == 0)
    .collect();
println!("{:?}", even_numbers); // Output:[2, 4]

In this example,filterThe method accepts a closure as a parameter to filter out even numbers.

6. Summary

Closures are one of the powerful features in Rust that allow functions to capture and manipulate variables in their definition environment. By understanding the types and features of closures, developers can write more flexible and efficient code.

This is the article about the anonymous functions of the closure in Rust and the capture environment. For more related contents of the anonymous functions of Rust closure, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!