Stängning (datavetenskap)
Inom datavetenskap är en closure en funktion som har en egen miljö. I denna miljö finns det minst en bunden variabel (ett namn som har ett värde, t.ex. ett tal). I stängningens miljö hålls de bundna variablerna i minnet mellan användningarna av stängningen.
Peter J. Landin gav denna idé namnet closure 1964. Programmeringsspråket Scheme gjorde closures populära efter 1975. Många programmeringsspråk som skapats efter den tiden har closures.
Anonyma funktioner (funktioner utan namn) kallas ibland felaktigt för closures. De flesta språk som har anonyma funktioner har också closures. En anonym funktion är också en closure om den har en egen miljö med minst en bunden variabel. En anonym funktion utan egen miljö är inte en closure. En namngiven closure är inte anonym.
Stängningar och förstklassiga funktioner
Värden kan vara siffror eller någon annan typ av data, t.ex. bokstäver, eller datastrukturer som består av enklare delar. I reglerna för ett programmeringsspråk är första klassens värden värden som kan ges till funktioner, returneras av funktioner och bindas till ett variabelnamn. Funktioner som tar emot eller returnerar andra funktioner kallas för funktioner av högre ordning. De flesta språk som har funktioner som första klassens värden har också funktioner av högre ordning och closures.
Ta till exempel en titt på följande Scheme-funktion:
I det här exemplet är lambdauttrycket (lambda (book) (>= (book-sales book) threshold)) en
del av funktionen best-selling-books
. När funktionen körs måste Scheme göra värdet av lambdauttrycket. Det gör det genom att skapa en closure med koden för lambda och en referens till variabeln threshold,
som är en fri variabel inom lambda. (En fri variabel är ett namn som inte är bundet till ett värde).
Filterfunktionen kör sedan avslutningen på varje bok i listan för att välja vilka böcker som ska returneras. Eftersom stängningen själv har en referens till tröskelvärdet
kan stängningen använda det värdet varje gång filter
kör stängningen. Själva funktionen filter
kan skrivas i en helt separat fil.
Här är samma exempel omskrivet i ECMAScript (JavaScript), ett annat populärt språk med stöd för closures:
ECMAScript använder ordet funktion i
stället för lambda
och metoden Array.filter i
stället för filterfunktionen, men i övrigt gör koden samma sak på samma sätt.
En funktion kan skapa en stängning och returnera den. Följande exempel är en funktion som returnerar en funktion.
I systemet:
I ECMAScript:
I stängningsmiljön behålls de bundna variablerna f
och dx
efter det att den omslutande funktionen (derivatan) har
återgått. I språk utan closures skulle dessa värden gå förlorade efter att den omslutande funktionen har återvänt. I språk med closures måste en bunden variabel behållas i minnet så länge som en closure har den.
En stängning behöver inte bildas med hjälp av en anonym funktion. Programmeringsspråket Python har till exempel begränsat stöd för anonyma funktioner, men det har stängningar. Ovanstående ECMAScript-exempel skulle till exempel kunna implementeras i Python på följande sätt:
I det här exemplet utgör funktionen gradient en slutenhet tillsammans med variablerna f och dx. Den yttre omslutande funktionen derivativ returnerar denna slutenhet. I det här fallet skulle en anonym funktion också fungera.
Python måste ofta använda namngivna funktioner i stället eftersom dess lambdauttryck endast kan innehålla andra uttryck (kod som returnerar ett värde) och inte påståenden (kod som har effekter men inget värde). Men i andra språk, t.ex. Scheme, returnerar all kod ett värde; i Scheme är allting ett uttryck.
Användning av stängningar
Stängningar har många användningsområden:
- Utvecklare av programvarubibliotek kan låta användarna anpassa beteendet genom att skicka closures som argument till viktiga funktioner. En funktion som sorterar värden kan t.ex. acceptera ett stängningsargument som jämför de värden som ska sorteras enligt ett användardefinierat kriterium.
- Eftersom closures fördröjer utvärderingen - dvs. de "gör" ingenting förrän de anropas - kan de användas för att definiera kontrollstrukturer. Till exempel definieras alla Smalltalks standardkontrollstrukturer, inklusive grenar (if/then/else) och slingor (while och for), med hjälp av objekt vars metoder accepterar closures. Användare kan också enkelt definiera sina egna kontrollstrukturer.
- Flera funktioner kan produceras som är nära varandra i samma miljö, vilket gör det möjligt för dem att kommunicera privat genom att ändra miljön (på språk som tillåter detta).
I systemet
- Closures kan användas för att implementera objektsystem.
Anmärkning: Vissa talare kallar alla datastrukturer som binder en lexikalisk miljö för en closure, men termen hänvisar vanligtvis specifikt till funktioner.
Frågor och svar
F: Vad är en avslutande examen i datavetenskap?
S: En closure är en funktion som har en egen miljö.
F: Vad innehåller miljön i en slutenhet?
S: Miljön för en slutenhet innehåller minst en bunden variabel.
Fråga: Vem gav idén om slutning sitt namn?
Svar: Peter J. Landin gav namnet till stängningsidén 1964.
Fråga: Vilket programmeringsspråk gjorde closures populära efter 1975?
Svar: Programmeringsspråket Scheme gjorde stängningar populära efter 1975.
Fråga: Är anonyma funktioner och closures samma sak?
S: Anonyma funktioner kallas ibland felaktigt för closures, men alla anonyma funktioner är inte closures.
Fråga: Vad gör en anonym funktion till en closure?
Svar: En anonym funktion är en closure om den har en egen miljö med minst en bunden variabel.
Fråga: Är en namngiven slutning anonym?
Svar: Nej, en namngiven stängning är inte anonym.