Rust — концепция захвата переменных с помощью замыкателей
В Rust мы можем захватывать переменные через замыкания. Замыкания — это анонимные функции, которые помогают нам сохранять переменные или передавать аргументы другим функциям. Замыкания могут быть созданы из одного места, а затем могут быть вызваны в любом месте, и они могут захватывать значения из своей определенной области.
При захвате переменных Rust использует для этого следующие методы:
- по ссылке: (&T)
- по значению: Т
- по изменяемой ссылке: (&mut T)
Пример 1:
Rust
// Rust code by reference fn main() { let var = String::from( "GeeksforGeeks" ); let name = || println!( "`Name`: {}" , var); name(); //calling the closure } |
Выход:
Объяснение:
В этом примере замыкание используется для вывода значения, которое заимствует (`&`) 'var' , и сохраняет заимствование и замыкание в переменной 'name' . Это останется там до тех пор, пока ' name' не будет использовано ранее. Как мы знаем, println! требует только аргументов, которые ссылаются на неизменяемые, поэтому ограничений нет. Имя закрытия вызывается с использованием заимствования.
Пример 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(); } |
Выход:
Объяснение:
В этом примере мы использовали замыкание count_closure, которое может принимать либо изменяемый инкремент счетчика, либо переменную-счетчик (неизменяемую). Мы использовали mut, так как вызов нашего замыкания мутирует с замыканием, для которого требуется выходной параметр. Здесь мы объявили I, который хранит количество вызовов замыкания и соответственно увеличивается.
Пример 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(); } |
Выход:
Объяснение:
В этом примере мы импортировали трейт std::mem , который помогает нам управлять памятью после разыменования переменной. Мы создали переменную с именем moving_variable и выделили память в куче со значением 5. Поскольку mem::drop требует типажа (T), поэтому она принимает значение. Переменная типа копирования будет копироваться в замыкание, не затрагивая исходное замыкание. variable_used использует переменную только один раз, поэтому она вызывается только один раз.