Open In App

Rust – Functions With Closure as Parameter

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

In Rust, there are anonymous functions that accept closure as parameters. In closures, we are generally not required to annotate types of parameters or return values as opposed to functions. Closures are stored in variables and are used without requiring to name them and exposing them to users of the code libraries. Closures are generally used for inferring the variable types. Type annotations are required for applying functions as types are generally part of an explicit interface that is exposed to the user’s code library.

While accepting closures as input parameters, the closure’s type is annotated with traits.

Before proceeding with the example, we need to know some terms related to traits:

  • Fn refers to closures that use captured value by reference
  • FnOnce refers to the closure that is used by capture by value.

Example 1:

Rust




// Rust code for Functions With Closure as Parameter
fn gfg<G>(f: G) where
      
    G: FnOnce() {
  
    f();
}
#[allow(dead_code)]
  
fn apply_function<G>(f: G) -> i32 where
    G: Fn(i32) -> i32 {
    f(3)
}
  
fn main() {
    use std::mem;
  
    let string_one = "Hackathons";
    let mut string_two = "GFG ".to_owned();
    let value = || {
        
        // `greeting` is by reference: requires `Fn`.
        println!("GeeksforGeeks {}.", string_one);
        string_two.push_str("Courses");
        println!("Learning Coding from {}.", string_two);
         
        mem::drop(string_two);
    };
    gfg(value);
}


Output:

 

Explanation:

In this example, we have declared Fn and FnOnce as the two traits. Here, <G> refers to G which is a Generic type parameter. gfg is declared as a function that takes a closure argument and calls it. The closure G: FnOne does not take any input parameters and therefore does not return anything also at the same time. The function apply_funvyion takes a closure of a 32-bit integer and returns it as well. The std::mem is used for the management of memory and it provides basic functions that deals with memory. We have declared two strings string_one and string_two (which are mutable). string_two is mutable in nature and it is a noncopy type and the to_owned is a borrowed concept that is responsible for borrowing data. Now, we have declared a variable named ‘value’ that captures the two variables string_one by reference and string_two by value. If we see the function closely, we can see that string_one requires a reference named ‘Fn’ and due to mutation string_two requires FnMit as a mutable reference so that it is captured. After our job is done, we drop ‘string_two’ using the std::mem so that string_two is captured by value which in turn requires Fn) once again. Lastly, call the function gfg and pass ‘value’ as a closure.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads