Замыкание (программирование)
Материал из Википедии — свободной энциклопедии
В программировании, Замыкание (англ. closure) — это процедура, которая ссылается на свободные переменные в своём лексическом контексте.
Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.
Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.
Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.
Пример работы замыканий на Scheme:
(define (make-adder n) ; возвращет замкнутое лямбда-выражение (lambda (x) ; в котором x - связанная переменная, (+ x n))) ; а n - свободная (захваченная из внешнего контекста)
(define add1 (make-adder 1)) ; делаем процедуру для прибавления 1 (add1 10) ; печатает 11
(define sub1 (make-adder -1)); делаем процедуру для вычитания 1 (sub1 10) ; печатает 9
[править] Реализации замыкания в языках программирования
Выше был показан пример на языке Scheme, но реализация данной концепции есть и во многих других языках программирования.
- PHP не имеет встроенной возможности замыкания, но, чтобы обойти данный недостаток, используют одноименный шаблон проектирования, который реализуется в библиотеке Николаса Нассара.
- Java релизует концепцию замыкания с помощью анонимных классов. Анонимный класс имеет доступ к полям класса, в лексическом контексте которого он определен, а так же к переменным с модификатором final в лексическом контексте метода.
class CalculationWindow extends JFrame { private JButton btnSave; ... public final calculateInSeparateThread(final URI uri) { // The expression "new Runnable() { ... }" is an anonymous class. Runnable runner = new Runnable() { void run() { // It can access final local variables: calculate(uri); // It can access private fields of the enclosing class: btnSave.setEnabled(true); } }; new Thread(runner).start(); } }