Замыкание

Материал из Энциклопедия о программировании
Перейти к: навигация, поиск

Замыкание (closure) в программировании — запоминание и возможное применение внешних элементов (чаще всего просто переменных/констант) находящихся в области контекста (в области видимости и реже в пространстве имен) в котором определена сущность запоминающая эти данные, но не содержащая их в себе; по неведанным причинам это крайне важная и значимая в программировании вещь, посему считается, что она должна быть в любом языке программирования; сложная в технической реализации фича без наличия которой могут обсмеять, именно по этому каждый уважающий себя язык программирования старается реализовать это всеми силами попутно соревнуясь с другими языками в кошмарности данной реализации и улучшая её от версии к версии.

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

Эталоном красоты реализации замыканий считается ECMAScript (более известный под диалектом JavaScript), там это реализовано в виде вложенной функции ибо ECMAScript помешан на функциях и там они являются типами данных. Поскольку именно в ECMAScript впервые был нормально и лаконично реализован механизм замыканий через функции, то считается, что замыкания должны быть реализованы именно функциями. В той же Википедии долгое время в статье описывающей замыкания речь шла только о функциях, якобы замыкание это функция в функции и никак иначе.

Замыкание (англ. closure) — функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся её параметрами. Говоря другим языком, замыкание — функция, которая ссылается на свободные переменные в своём контексте.

При этом нигде не говорится, что замыкания должны быть реализованы именно в функциях, однако последовав примеру ECMAScript так было сделано и в других популярных языках программирования. Однако в помешанной на классах Java замыкания реализованы в виде внутренних классов, хотя смотрится ужасно.

На деле технически замыкания реализовываются достаточно просто:

  1. Внутри сущности реализовывающей замыкание собираются все ссылки на внешние элементы определённые в том же контексте, что и сама сущность.
  2. Собранные элементы копируются извне и остаются в памяти, если в них есть ещё внешние ссылки, то они так же собираются.
  3. В конечном счёте остаётся уже не зависящий от контекста жёсткий код на который можно ссылаться из сущности реализовывающей замыкание.