Замикання (Closures)
Замикання — це функції, які можуть захоплювати навколишнє середовище. Наприклад, замикання, що захоплює змінну x:
|val| val + x
Синтаксис і можливості замикань роблять їх дуже зручними для використання на льоту. Виклик замикання точно такий самий, як виклик функції. Однак і типи вхідних даних, і тип повернення можуть бути виведені, а імена вхідних змінних мають бути вказані.
Інші характеристики замикань включають:
- використання
||замість()навколо вхідних змінних. - необов’язкове обмеження тіла (
{}) для однорядкового виразу (обов’язково в іншому разі). - можливість захоплювати змінні зовнішнього середовища.
fn main() {
let outer_var = 42;
// Звичайна функція не може посилатися на змінні в навколишньому середовищі
//fn function(i: i32) -> i32 { i + outer_var }
// TODO: uncomment the line above and see the compiler error. The compiler
// suggests that we define a closure instead.
// Замикання анонімні, тут ми прив'язуємо їх до посилань.
// Анотація ідентична анотації функції, але є необов'язковою,
// як і `{}` навколо тіла. Ці безіменні функції
// присвоюються змінним із відповідними назвами.
let closure_annotated = |i: i32| -> i32 { i + outer_var };
let closure_inferred = |i | i + outer_var ;
// Виклик замикань.
println!("closure_annotated: {}", closure_annotated(1));
println!("closure_inferred: {}", closure_inferred(1));
// Після того як тип замикання було виведено, його не можна знову вивести з іншим типом.
//println!("cannot reuse closure_inferred with another type: {}", closure_inferred(42i64));
// TODO: uncomment the line above and see the compiler error.
// Замикання без аргументів, яке повертає `i32`.
// Тип повернення виводиться.
let one = || 1;
println!("closure returning one: {}", one());
}