Rust — замыкание как входной параметр

Опубликовано: 16 Февраля, 2023

В Rust Closures можно использовать в качестве входных параметров. Замыкания — это функции, которые оборачивают функции для целей повторного использования, которые помогают захватывать переменные во внешней среде. Замыкания закрываются при использовании в функциях, а для исключения одного выражения ({}) используется. Аргументы закрытия записываются между вертикальными чертами (|), а тело представляет собой выражение.

Пример 1:

Rust




// Rust example  of a closure
#![allow(unused_variables)]
fn main() {
let closure_variable = |x: i32| x * 10;
  
assert_eq!(100,closure_variable(10));
}

Выход:

Эта программа утверждает, является ли выражение x* 10 = 100 или нет, когда мы передаем замыкание в качестве параметра в выражении. Здесь переменная закрытия объявлена как closure_variable и ссылается на x (32-битный тип). Теперь мы используем assert_eq! макрос, чтобы проверить, является ли выражение истинным или ложным. Если утверждение не выполняется, Rust паникует

Пример 2:

Rust




// Rust code
#![allow(unused_variables)]
fn main() {
let closure_variable = |x: i32| x * 10;
  
assert_eq!(90,closure_variable(10));
// println!("{:?}",plus_one);
}

Выход:

Принимая замыкания в качестве входных параметров, тип замыкания аннотируется трейтами.

Прежде чем перейти к примеру, рассмотрим некоторые термины, связанные с чертами:

  • Fn относится к замыканиям, которые используют захваченное значение по ссылке.
  • FnOnce относится к замыканию, которое используется при захвате по значению.

Пример 3:

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 = "Courses";
    let mut string_two = "GFG".to_owned();
    let value = || {
        
        // `greeting` is by reference: requires `Fn`.
        println!("GFG {}.", string_one);
        string_two.push_str("Practice");
        println!("Practising Coding on {}.", string_two);
         
        mem::drop(string_two);
    };
    gfg(value);
}

Выход:

Объяснение:

В этом примере мы объявили Fn и FnOnce как две черты. Здесь <G> относится к G, который является параметром универсального типа. gfg объявлен как функция, которая принимает аргумент закрытия и вызывает его. Замыкание G:FnOne не принимает никаких входных параметров и, следовательно, ничего не возвращает одновременно. Функция apply_funvyion принимает замыкание 32-битного целого числа и также возвращает его. std::mem используется для управления памятью и предоставляет основные функции, связанные с памятью. Мы объявили две строки string_one и string_two (изменяемые). string_two является изменяемым по своей природе и является некопируемым типом, а to_owned является заимствованной концепцией, отвечающей за заимствование данных. Теперь мы объявили переменную с именем value, которая захватывает две переменные string_one по ссылке и string_two по значению. Если мы внимательно посмотрим на функцию, мы увидим, что для string_one требуется ссылка с именем «Fn», а из-за мутации string_two требуется FnMit в качестве изменяемой ссылки, чтобы она была захвачена. После того, как наша работа выполнена, мы удаляем 'string_two' с помощью std::mem, так что string_two захватывается значением, которое, в свою очередь, требует Fn) еще раз. Наконец, вызовите функцию gfg и передайте «значение» в качестве замыкания.