Open In App

Rust – Concept of Capturing Variables with Closers

Last Updated : 14 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

In Rust, we can capture variables via Closures. Closures are anonymous functions that help us in saving variables or pass arguments to other functions. Closures can be created from one place and then can be called anywhere and they can capture values from their defined scope.

While capturing variables, Rust uses the following methods to do this:

  • by reference: (&T)
  • by value: T
  • by mutable reference: (&mut T)

Example 1:

Rust




// Rust code by reference
fn main() {
      
    let var = String::from("GeeksforGeeks");
    let name = || println!("`Name`: {}", var);
    name(); //calling the closure
    }


Output:

 

Explanation:

In this example, a closure is used to print the value that borrows (`&`) ‘var’ and stores the borrow and the closure in the ‘name’  variable. This would remain there until ‘name’ is used previously. As we know that println! requires only arguments that reference immutable therefore there are no restrictions imposed. The closure name is called using the borrow.

Example 2:

Rust




// Rust code for by value T
fn main() {
   
    let mut count = 0;
    let mut i= 0;
     
    let mut count_closure = || {
        count += 10;
        println!("`count:{}, value: {}`", i, count);
        i+=1;
    };
 // Calling the closure 'count_closure' using a mutable borrow.
    count_closure();
    count_closure();
    count_closure();
    }


Output:

 

Explanation:

In this example, we have used a closure ‘count_closure’ that can take either a mutable count incrementor or a counter variable (non-mutable). We have used mut since calling our closure mutates with the closure that requires an out parameter. Here, we have declared an I that stores the number of times the closure is called and is incremented accordingly.

Example 3:

Rust




// Rust code for by mutable reference: (&mut T)
fn main() {
 use std::mem;
       
    let moving_variable = Box::new(5);
    let variable_used = || {
        println!("`movable variable value`: {:?}", moving_variable);
        mem::drop(moving_variable);
    };
    variable_used();
}


Output:

 

Explanation:

In this example, we have imported the std::mem trait that helps us in managing the memory once the variable is dereferenced. We have created a variable named moving_variable and have allocated memory on the heap that has a value of 5. As mem::drop requires a trait (T) therefore this takes a value. A copy-type variable would copy into the closure leaving the original closure unaffected. variable_used consumes the variable only once hence it is called one time only.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads