Затваряне (информатика)

Затваряне (на английски: closure) в програмирането е функция, която запазва (затваря) областта на видимост, в която е дефинирана, поне докато съществува референция към нея.

В повечето програмни езици обектите се унищожават при излизането от областта на видимост, в която са дефинирани. Използването на затваряне гарантира, че обектите, дефинирани в неговата област на видимост, няма да бъдат унищожени, докато то е използвано или реферирано.

ПримерРедактиране

В долните примери функция, дефинираща област на видимост, връща затваряне, което използва локална променлива а във функцията. Както е видимо, локалната променлива продължава да съществува, въпреки че функцията е завършила. В повечето езици, които поддържат области на видимост, а ще бъде унищожена при изход от функцията.

ПсевдокодРедактиране

функция Ф()
   а = 5;
   з = затваряне
      а = а + 1;
      върни а;
   край;
   върни з;
край;
х = ф();
х(); // -> 6
х(); // -> 7

RubyРедактиране

def f
	a = 5
	Proc.new {
		a += 1
		a
	}
end
x = f
x.call # -> 6
x.call # -> 7

Привидни затварянияРедактиране

В някои езици се поддържат привидни затваряния. Те не запазват областта на видимост, в която са дефнирани, но могат да се използват за удобство при фукции, взимащи функция за параметър. В долните примери затварянията никога не са използвани извън областта на видимост, в която са дефинирани, и следователно работят. При опит да бъдат използвани извън нея би се получило недефинирано поведение.

Пример 1Редактиране

Това е валиден код за С++, поддържан от GCC 3.7. Функция, която връща сбор на елементите на вектор:

int sum(const vector<int>& values)
{
   int s = 0;
   void closure(int n)
   {
       s += n;
   }
   foreach(values.begin(), values.end(), closure);
   return s;
}

Пример 2Редактиране

Това отново е пример от С++. Този синтаксис е предложен за поддръжката на затваряния в С++ в стандарта С++09. Тук се комбинра затваряне и анонимна функция:

int sum(const vector<int>& values)
{
   int s=0;
   foreach(values.begin(), values.end(), void <>(int n){ s += n; });
   return s;
}

Вижте същоРедактиране