Замыкание (программирование)

В программировании, Замыкание (англ. closure) — это процедура, которая ссылается на свободные переменные в своём лексическом контексте.

Замыкание, так же как и экземпляр объекта, есть способ представления функциональности и данных, связанных и упакованных вместе.

Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.

Замыкание связывает код функции с её лексическим окружением (местом, в котором она определена в коде). Лексические переменные замыкания отличаются от глобальных переменных тем, что они не занимают глобальное пространство имён. От переменных в объектах они отличаются тем, что привязаны к функциям, а не объектам.


Пример работы замыканий на Scheme:

(define (make-adder n)       ; возвращет замкнутое лямбда-выражение
  (lambda (x)                ; в котором x - связанная переменная,
    (+ x n)))                ; а n - свободная (захваченная из внешнего контекста)
(define add1 (make-adder 1)) ; делаем процедуру для прибавления 1
(add 1 10)                    ; печатает 11
(define sub1 (make-adder -1)); делаем процедуру для вычитания 1
(sub 1 10)                    ; печатает 9

Реализации замыкания в языках программирования

Выше был показан пример на языке Scheme, но реализация данной концепции есть и во многих других языках программирования.

  • 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();
    }
}
 
Начальная страница  » 
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ы Э Ю Я
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
0 1 2 3 4 5 6 7 8 9 Home