Понимание замыканий
Часть раздела Логика и управление потоком путешествия по Dart на Coddy. Урок 46 из 65.
closure — это особый тип function, который «помнит» переменные из места, где он был создан, даже после завершения работы исходного контекста. Представьте его как function, который повсюду носит с собой частичку места своего рождения.
Когда вы создаёте function внутри другой function, внутренняя function получает доступ к переменным внешней function. Отличительной особенностью closure является то, что этот доступ сохраняется даже после того, как внешняя function completed своё выполнение.
Function createGreeting(String name) {
return () {
return "Hello, $name!";
};
}В этом примере анонимная функция, возвращаемая createGreeting, является замыканием. Она захватывает параметр name из окружающей области видимости. Даже после завершения выполнения createGreeting возвращённая функция всё ещё помнит, каким было значение name.
Замыкания невероятно полезны для создания специализированных функций или чистого поддержания состояния. Они позволяют создавать функции, настроенные в соответствии с окружением, в котором они были созданы, делая ваш код более гибким и мощным.
Задание
ЛегкоСоздайте программу, которая демонстрирует замыкания, создавая систему генерации персонализированных сообщений. Ваша программа будет создавать функции, которые «запоминают» определённую информацию и используют её для создания настроенных сообщений даже после завершения исходного контекста.
- Прочитайте строковый ввод, представляющий имя человека
- Прочитайте строковый ввод, представляющий тип приветствия (
"formal","casual"или"friendly") - Прочитайте строковый ввод, представляющий название компании
- Создайте функцию с именем
createMessageGenerator, которая принимает имя и тип приветствия в качестве параметров - Функция
createMessageGeneratorдолжна возвращать другую функцию (замыкание), которая: - Принимает название компании в качестве параметра
- Использует имя и тип приветствия из области видимости внешней функции
- Возвращает отформатированное сообщение на основе типа приветствия:
- Для
"formal":"Dear [name], we are pleased to welcome you to [company]." - Для
"casual":"Hey [name]! Welcome to [company]!" - Для
"friendly":"Hi [name], so glad you joined [company]!" - Вызовите функцию
createMessageGeneratorс вводом имени и типа приветствия, чтобы получить функцию-замыкание - Вызовите возвращённую функцию-замыкание с вводом названия компании, чтобы сгенерировать сообщение
- Выведите результаты в точном формате, показанном ниже
Например, если введены "Alice", "formal" и "TechCorp", ваша программа должна вывести:
Message Generator System
========================
Creating message generator for: Alice
Greeting type: formal
Company: TechCorp
========================
Generated message: Dear Alice, we are pleased to welcome you to TechCorp.
Message generation completed successfullyЕсли введены "Bob", "casual" и "StartupXYZ", ваша программа должна вывести:
Message Generator System
========================
Creating message generator for: Bob
Greeting type: casual
Company: StartupXYZ
========================
Generated message: Hey Bob! Welcome to StartupXYZ!
Message generation completed successfullyЕсли введены "Carol", "friendly" и "InnovateLab", ваша программа должна вывести:
Message Generator System
========================
Creating message generator for: Carol
Greeting type: friendly
Company: InnovateLab
========================
Generated message: Hi Carol, so glad you joined InnovateLab!
Message generation completed successfullyВаша программа должна демонстрировать замыкания, создавая функцию, которая возвращает другую функцию. Возвращённая функция (замыкание) должна иметь доступ к переменным из области видимости внешней функции (name и greeting type) даже после завершения выполнения внешней функции. Используйте условные операторы, чтобы определить подходящий формат сообщения на основе введённого типа приветствия.
Попробуйте сами
import 'dart:io';
void main() {
// Прочитать ввод
String? name = stdin.readLineSync();
String? greetingType = stdin.readLineSync();
String? company = stdin.readLineSync();
// Отобразить заголовок системы
print("Message Generator System");
print("========================");
print("Creating message generator for: $name");
print("Greeting type: $greetingType");
print("Company: $company");
print("========================");
// TODO: Напишите свой код ниже
// Create the createMessageGenerator function that returns a closure
// Вызовите функцию и сгенерируйте сообщение
// Вывести итоговые результаты
print("Generated message: \$message");
print("Message generation completed successfully");
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Продвинутая работа со списками
Свойства списка: first и lastСостояние списка: isEmpty и isNotEmptyРазворот спискаДобавление в список: insertУдаление из списка: removeWhereПоиск в списке: indexOfСортировка спискаПеремешивание спискаИтоги — Органайзер списков4Продвинутая работа с Map
Итерация по MapПроверка ключей и значенийСвойства Map: keys и valuesУсловное добавление: putIfAbsentУдаление записей из MapВложенные MapИтоги — Обновление инвентаря2Функциональные операции со списками
Преобразование с помощью 'map'Фильтрация с помощью 'where'Использование '.toList()'Проверка условий с помощью 'any'Условия с 'every'Поиск с помощью 'firstWhere'Повторение — фильтрация данных5Проект: Калькулятор корзины
Настройка проектаДобавление товаров в корзину3Множества
Что такое множество?Создание множестваДобавление и удаление элементовПроверка наличия элементов в множествеПреобразование списка в множествоОбъединение множествПересечение множествРазность множествИтоги: уникальный список гостейПотренируйтесь самостоятельно: Онлайн-компилятор Dart