Изучение Замыканий в Rust и Захвата Окружающей Среды

Beginner

This tutorial is from open-source community. Access the source code

Введение

В этом лабе мы исследуем замыкания, которые являются функциями в Rust, которые могут захватывать окружающую среду, ссылаясь на переменные за пределами их области действия.

Примечание: Если в лабе не указано имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать main.rs, скомпилировать и запустить его с помощью rustc main.rs &&./main.

Замыкания

Замыкания - это функции, которые могут захватывать окружающую среду. Например, замыкание, которое захватывает переменную x:

|val| val + x

Синтаксис и возможности замыканий делают их очень удобными для即兴ового использования. Вызов замыкания происходит точно так же, как вызов функции. Однако как тип ввода, так и тип возврата могут быть проинференцированы, а имена переменных ввода должны быть указаны.

Другие характеристики замыканий включают в себя:

  • использование || вместо () вокруг переменных ввода.
  • необязательное обрамление тела ({}) для одного выражения (обязательно в противном случае).
  • возможность захвата внешних переменных окружения.
fn main() {
    let outer_var = 42;

    // Обычная функция не может ссылаться на переменные в окружающей среде
    //fn function(i: i32) -> i32 { i + outer_var }
    // TODO: раскомментируйте строку выше и посмотрите на ошибку компилятора. Компилятор
    // предлагает определить замыкание вместо этого.

    // Замыкания анонимны, здесь мы связываем их с ссылками
    // Аннотация идентична аннотации функции, но является необязательной
    // так же, как и `{}` вокруг тела. Эти именованные функции
    // назначаются переменным с соответствующими именами.
    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: раскомментируйте строку выше и посмотрите на ошибку компилятора.

    // Замыкание, не принимающее аргументов, которое возвращает `i32`.
    // Тип возврата проинференцирован.
    let 1;
    println!("closure returning one: {}", one());

}

Резюме

Поздравляем! Вы завершили лабу по Замыканиям. Вы можете практиковаться в более лабах в LabEx, чтобы улучшить свои навыки.