Захват значений
Часть раздела Логика и управление потоком путешествия по Swift на Coddy — урок 40 из 56.
Замыкание запоминает переменные, которые находились в области видимости в момент его создания. Тело замыкания может считывать и даже изменять их позже, даже после того, как внешняя функция завершила выполнение. Это называется захватом.
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next()) // 1
print(next()) // 2
print(next()) // 3Каждый вызов makeCounter дает вам совершенно новый count, поэтому два счетчика никогда не разделяют состояние:
let a = makeCounter()
let b = makeCounter()
print(a()) // 1
print(b()) // 1
print(a()) // 2Захват переменных — это то, что делает замыкания более мощными, чем обычные функции: они несут в себе состояние. Вы увидите тот же прием в JavaScript, Python и многих других языках.
Задание
СреднеСоздайте небольшую фабрику счетчиков.
Определите функцию makeCounter(start: Int, step: Int), которая возвращает замыкание типа () -> Int. Каждый вызов замыкания возвращает следующее значение: первый вызов возвращает start, следующий возвращает start + step, затем start + 2*step и так далее.
Прочитайте три целых числа из входных данных: start, step и n. Создайте счетчик с параметрами start и step, затем вызовите его n раз и выведите каждый результат на отдельной строке.
Для входных данных 5 / 3 / 4 вывод будет следующим:
5
8
11
14Шпаргалка
Замыкания захватывают переменные из своей области видимости, сохраняя состояние даже после завершения работы внешней функции:
func makeCounter() -> () -> Int {
var count = 0
return {
count += 1
return count
}
}
let next = makeCounter()
print(next()) // 1
print(next()) // 2Каждый вызов фабричной функции создает независимую захваченную переменную — два счетчика никогда не разделяют состояние.
Попробуйте сами
let start = Int(readLine()!)!
let step = Int(readLine()!)!
let n = Int(readLine()!)!
// TODO: makeCounter(start:step:) -> () -> Int, которая захватывает текущее значение
// затем вызовите её n раз и выведите каждый результат
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Логика и управление потоком
1Строки в деталях
Подсчет и индексыРегистр и удаление пробеловПоиск в строкахРазделение и объединениеЗамена подстрокИтоги — Проверка имени пользователя4Множества
Создание множествОбъединение и пересечениеРазность и симметрическая разностьПодмножество и надмножествоИтоги — Фильтр тегов7Проект — Трекер привычек
Обзор проектаОтметить выполнение10Проект — Движок викторины
Обзор проектаЗадаем вопросы2Диапазоны и шаги
Закрытые и полуоткрытыеШагМетоды диапазоновДиапазоны в SwitchИтоги: Сетка календаря