Введение
В этом лабе мы исследуем замыкания, которые являются функциями в 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, чтобы улучшить свои навыки.