Что такое замыкание?
Часть раздела Logic & Flow путешествия по Lua на Coddy — урок 14 из 54.
Вы узнали, что функции могут храниться в переменных, передаваться в качестве аргументов и возвращаться из других функций. Теперь мы изучим одно из самых мощных последствий этого: замыкания.
Замыкание возникает, когда вложенная функция «запоминает» локальные переменные из своей внешней функции, даже после того, как эта внешняя функция завершила выполнение. Поначалу это может показаться странным — как переменная может продолжать существовать после того, как функция, создавшая её, завершила работу?
Вот простой пример, демонстрирующий эту концепцию:
function createCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = createCounter()
print(counter()) -- Вывод: 1
print(counter()) -- Вывод: 2
print(counter()) -- Вывод: 3Когда вызывается createCounter(), она создает локальную переменную count и возвращает анонимную функцию. Обычно ожидается, что count исчезнет после завершения работы createCounter(). Но возвращаемая функция по-прежнему имеет доступ к count — она «замыкает» эту переменную.
Каждый раз, когда вы вызываете counter(), она обращается к той же переменной count, которая была создана, когда createCounter() запустилась впервые. Внутренняя функция несет в себе свое окружение, сохраняя состояние между вызовами.
Задание
ЛегкоНапишите функцию createMultiplier, которая создает функцию-множитель с определенным коэффициентом, а затем сразу использует ее для умножения заданного числа.
Логика:
- Создайте вложенную функцию внутри
createMultiplier, которая принимает параметр-число - Вложенная функция должна умножать свой параметр на
factorиз внешней функции - Вложенная функция образует замыкание, запоминая значение
factor - Вызовите функцию-множитель с параметром
numberи верните результат
Параметры:
factor(число): Значение множителяnumber(число): Число для умножения
Возвращает:
- Результат умножения
numberнаfactor(число)
Шпаргалка
Замыкание возникает, когда вложенная функция «запоминает» локальные переменные из своей охватывающей функции, даже после того, как внешняя функция завершила выполнение.
Внутренняя функция несет в себе свое окружение, сохраняя состояние между вызовами:
function createCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = createCounter()
print(counter()) -- Вывод: 1
print(counter()) -- Вывод: 2
print(counter()) -- Вывод: 3Когда вызывается createCounter(), она создает локальную переменную count и возвращает анонимную функцию. Возвращаемая функция по-прежнему имеет доступ к count — она «замыкает» эту переменную, даже после того, как внешняя функция завершила выполнение.
Попробуйте сами
function createMultiplier(factor, number)
local multiply = function(x)
return x * factor
end
-- Используйте функцию multiply ниже
endВ этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Продвинутая итерация таблиц
Итерация с помощью pairs()Итерация с помощью ipairs()pairs() против ipairs()Повторение — Лист персонажа2Дополнительные функции библиотеки table
table.concat()Создание таблиц и unpack()table.sort()Пользовательская сортировка с помощью функцийИтоги — Таблица рекордов3Продвинутые концепции функций
Возврат нескольких значенийВариативные функции (...)Функции как объекты первого классаАнонимные функцииЧто такое замыкание?Итоги — простой обработчик событий