Închidere (informatică)

În informatică, o închidere este o funcție care are un mediu propriu. În acest mediu, există cel puțin o variabilă legată (un nume care are o valoare, cum ar fi un număr). Mediul de închidere păstrează variabilele legate în memorie între două utilizări ale închiderii.

Peter J. Landin a dat acestei idei numele de closure în 1964. Limbajul de programare Scheme a popularizat închiderile după 1975. Multe limbaje de programare create după această dată au closures.

Funcțiile anonime (funcții fără nume) sunt uneori numite în mod greșit închideri. Cele mai multe limbaje care au funcții anonime au, de asemenea, funcții de închidere. O funcție anonimă este, de asemenea, o închidere dacă are un mediu propriu cu cel puțin o variabilă legată. O funcție anonimă care nu are un mediu propriu nu este o închidere. O închidere cu nume nu este anonimă.

Închideri și funcții de primă clasă

Valorile pot fi numere sau un alt tip de date, cum ar fi litere, sau structuri de date alcătuite din părți mai simple. În regulile unui limbaj de programare, valorile de primă clasă sunt valori care pot fi date funcțiilor, returnate de funcții și legate la un nume de variabilă. Funcțiile care preiau sau returnează alte funcții se numesc funcții de ordin superior. Majoritatea limbajelor care au funcții ca valori de primă clasă au, de asemenea, funcții de ordin superior și închideri.

De exemplu, aruncați o privire la următoarea funcție Scheme:

; Întoarceți o listă a tuturor cărților cu cel puțin TREI exemplare vândute. (define (best-selling-books threshold) (filter (lambda (book) (>= (book-sales book) threshold)) book-list)) book-list))

În acest exemplu, expresia lambda (lambda (lambda (carte) (>= (vânzări de cărți carte) prag))) face parte din funcția best-selling-books. Atunci când funcția este executată, Scheme trebuie să facă valoarea expresiei lambda. Face acest lucru realizând o închidere cu codul pentru lambda și o referință la variabila threshold, care este o variabilă liberă în interiorul lambdei. (O variabilă liberă este un nume care nu este legat de o valoare).

Funcția de filtrare execută apoi închiderea pe fiecare carte din listă pentru a alege cărțile care vor fi returnate. Deoarece închiderea însăși are o referință la prag, închiderea poate utiliza această valoare de fiecare dată când filtrul execută închiderea. Funcția de filtrare în sine poate fi scrisă într-un fișier complet separat.

Iată același exemplu rescris în ECMAScript (JavaScript), un alt limbaj popular cu suport pentru închideri:

// Întoarce o listă cu toate cărțile cu cel puțin 'prag' de exemplare vândute. function bestSellingBooks(threshold) { return bookList. filter( function(book) { return book. sales >= threshold; }     ); }

ECMAScript folosește aici cuvântul function în loc de lambda și metoda Array.filter în locul funcției filter, dar în rest codul face același lucru în același mod.

O funcție poate crea o închidere și o poate returna. Următorul exemplu este o funcție care returnează o funcție.

În schemă:

; Returnează o funcție care aproximează derivata lui f ; folosind un interval dx, care ar trebui să fie corespunzător de mic. (definește (derivată f dx) (lambda (x) (/ (- (f (+ x dx))) (f x))) dx))))))

În ECMAScript:

// Se returnează o funcție care aproximează derivata lui f // folosind un interval dx, care trebuie să fie corespunzător de mic. function derivative(f, dx) { return function(x) { return (f(x + dx) - f(x)) / dx; }; }; }

Mediul de închidere păstrează variabilele legate f și dx după ce funcția de închidere (derivată) se întoarce. În limbajele fără închideri, aceste valori s-ar pierde după ce funcția de închidere revine. În limbajele cu închideri, o variabilă legată trebuie să fie păstrată în memorie atâta timp cât o are orice închidere.

Nu este necesar ca o închidere să fie formată cu ajutorul unei funcții anonime. Limbajul de programare Python, de exemplu, are un suport limitat pentru funcțiile anonime, dar are închideri. De exemplu, un mod în care exemplul ECMAScript de mai sus ar putea fi implementat în Python este:

# returnează o funcție care aproximează derivata lui f # folosind un interval de dx, care ar trebui să fie corespunzător de mic. def derivative(f, dx): def gradient(x): return (f(x + dx) - f(x)) / dx return gradient

În acest exemplu, funcția numită gradient realizează o închidere împreună cu variabilele f și dx. Funcția exterioară de închidere numită derivată returnează această închidere. În acest caz, ar funcționa și o funcție anonimă.

def derivative(f, dx): return lambda x: (f(x + dx) - f(x)) / dx

Python trebuie să utilizeze adesea funcții numite în locul acestora, deoarece expresiile lambda pot conține doar alte expresii (cod care returnează o valoare) și nu declarații (cod care are efecte, dar nu are valoare). Dar în alte limbaje, cum ar fi Scheme, tot codul returnează o valoare; în Scheme, totul este o expresie.

Utilizări ale închiderilor

Închiderile au multe utilizări:

  • Proiectanții de biblioteci software pot permite utilizatorilor să personalizeze comportamentul prin transmiterea de închideri ca argumente la funcțiile importante. De exemplu, o funcție care sortează valori poate accepta un argument de închidere care compară valorile care urmează să fie sortate în funcție de un criteriu definit de utilizator.
  • Deoarece închiderile întârzie evaluarea - adică nu "fac" nimic până când nu sunt apelate - ele pot fi utilizate pentru a defini structuri de control. De exemplu, toate structurile de control standard din Smalltalk, inclusiv ramurile (if/then/else) și buclele (while și for), sunt definite folosind obiecte ale căror metode acceptă închideri. De asemenea, utilizatorii pot defini cu ușurință propriile structuri de control.
  • Se pot produce mai multe funcții care se închid în același mediu, permițându-le să comunice în mod privat prin modificarea acelui mediu (în limbajele care permit atribuirea).

În sistem

(define foo #f) (define bar #f) (let ((secret-message "none")) (set! foo (lambda (msg) (set! secret-message msg))) (set! bar (lambda () secret-message))) (display (bar)) ; afișează "none" (newline) (foo "ne întâlnim la docuri la miezul nopții") (display (bar)) ; afișează "ne întâlnim la docuri la miezul nopții"
  • Închiderile pot fi utilizate pentru a implementa sisteme de obiecte.

Notă: Unii vorbitori numesc închidere orice structură de date care leagă un mediu lexical, dar termenul se referă de obicei în mod specific la funcții.

Întrebări și răspunsuri

Î: Ce este o închidere în informatică?


R: O închidere este o funcție care are un mediu propriu.

Î: Ce conține mediul unei închideri?


R: Mediul unei închideri conține cel puțin o variabilă legată.

Î: Cine a dat numele ideii de închidere?


R: Peter J. Landin a dat numele ideii de închidere în 1964.

Î: Ce limbaj de programare a popularizat closure-urile după 1975?


R: Limbajul de programare Scheme a popularizat închiderile după 1975.

Î: Funcțiile anonime și închiderile sunt același lucru?


R: Funcțiile anonime sunt uneori numite în mod greșit închideri, dar nu toate funcțiile anonime sunt închideri.

Î: Ce face ca o funcție anonimă să fie o închidere?


R: O funcție anonimă este o închidere dacă are un mediu propriu cu cel puțin o variabilă legată.

Î: O închidere numită este anonimă?


R: Nu, o închidere numită nu este anonimă.

AlegsaOnline.com - 2020 / 2023 - License CC3