Arvutiteaduses on sulgemine funktsioon, millel on oma keskkond. Selline keskkond sisaldab vähemalt üht seotud muutujat — nime, millel on väärtus (näiteks arv või osuti). Sulgemine „seob“ selle funktsiooni juurde need muutujad ja hoiab neid mälus ka pärast seda, kui funktsiooni deklareerinud kontekst on lõppenud; see võimaldab funktsioonil kasutada ja muuta neid muutujaid hilisemal ajal.
Peter J. Landin andis sellele ideele 1964. aastal nime closure. Programmeerimiskeel Scheme tegi sulgemised populaarseks pärast 1975. aastat. Alates sellest ajast on sulgemiste tugi levinud paljudes programmeerimiskeeltes (näiteks JavaScript, Python, Ruby, Lisp-pere keeled ja teised), kus need pakuvad võimsaid abstraktsioone ja puhast viisi oleku kapseldamiseks.
Kuidas sulgemised töötavad
Sulgemine tekib siis, kui funktsioon (sisefunktsioon) viitab muutujatele, mis on defineeritud väliskontekstis (välisfunktsioonis). Kui välisfunktsioon lõpetab töö ja tagastab sisefunktsiooni, jääb selle sisefunktsiooni juurde alles viide väliskonteksti seotud muutujatele — see komplekt seotud muutujatest moodustabgi sulgemise keskkonna.
Lihtne illustratsioon (loogiline kirjeldus):
- välistesamm: defineeri funktsioon A, mis loob muutuja x ja defineerib funktsiooni B, mis kasutab x;
- tagastus: A tagastab funktsiooni B;
- jätkamine: isegi pärast A lõpetamist säilitab B juurdepääsu muutuja x väärtusele tänu sulgemisele.
Kus sulgemisi kasutatakse
- Püsiva oleku loomine ja andmete kapseldamine (privaatsete muutujate loomine ilma klassita).
- Tagasikutsed (callbacks) ja sündmusekäsitlejad, kus funktsioon peab säilitama konteksti hilisemateks väljakutseteks.
- Funktsionaalne programmeerimine — osaliselt rakendamine (partial application), currying ja kõrgema järgu funktsioonid kasutavad sageli sulgemisi.
- Anname funktsioonile juurdepääsu sisemisele konfiguratsioonile ilma globaalseid muutujad kasutamata.
Mälu ja eluiga
Kuna sulgemine hoiab omas keskkonnas muutujaid mälus, tuleb olla tähelepanelik mälu kasutamise suhtes. Tänapäevased prügikoristajad (garbage collectors) vabastavad mälu, kui sulgemisi ei viitata enam kuskilt. Kuid pikaealised või palju mälu hõlmavad sulgemised võivad kaasa tuua ootamatu mälu tarbimise, kui neid hoitakse ringkäidavas struktuuris või globaalsete registrite kaudu.
Märkus anonüümsete funktsioonide kohta
Anonüümseid funktsioone (funktsioone, millel pole nime) nimetatakse mõnikord ekslikult sulgemisteks. Enamikus keeltes, kus on anonüümsed funktsioonid, on ka sulgemised, kuid need kaks mõistet ei ole identsed: anonüümne funktsioon on sulgemine ainult siis, kui tal on oma keskkond, millel on vähemalt üks seotud muutuja. Anonüümne funktsioon, millel puudub oma keskkond, ei ole sulgemine. Samuti võib sulgemine olla nimega — nimeline sulgemine ei ole anonüümne.
Lisaks on oluline eristada leksikaalset (staatilist) ja dünaamilist scopingut: enamik tänapäevaseid sulgemisi põhinevad leksikaalsel scopingul, kus seotud muutujate sidumine toimub definitsiooni ajal, mitte funktsiooni käivituse ajal.
Kui soovite, võin lisada lühikese näite konkreetse programmeerimiskeelega (nt JavaScript või Python), et sulgemiste tööd koodi näitel illustreerida.