Zárás (informatika)

A számítástechnikában a lezárás egy olyan függvény, amely saját környezettel rendelkezik. Ebben a környezetben van legalább egy kötött változó (egy név, amelynek értéke van, például egy szám). A zárlat környezete a kötött változókat a zárlat használata között a memóriában tartja.

Peter J. Landin 1964-ben adta ennek az ötletnek a lezárás nevet. A Scheme programozási nyelv 1975 után tette népszerűvé a lezárásokat. Sok, ezután készült programozási nyelv rendelkezik zárlatokkal.

A névtelen függvényeket (név nélküli függvények) néha tévesen lezárásoknak nevezik. A legtöbb olyan nyelv, amely névtelen függvényekkel rendelkezik, rendelkezik lezárásokkal is. Egy névtelen függvény akkor is zárlat, ha van saját környezete legalább egy kötött változóval. Egy névtelen függvény, amelynek nincs saját környezete, nem zárlat. A névvel ellátott zárlat nem névtelen.

Lezárások és első osztályú függvények

Az értékek lehetnek számok vagy más típusú adatok, például betűk, vagy egyszerűbb részekből álló adatszerkezetek. Egy programozási nyelv szabályai szerint az első osztályú értékek olyan értékek, amelyeket függvényeknek adhatunk meg, függvények adnak vissza, és változó névhez köthetők. Az olyan függvényeket, amelyek más függvényeket vesznek át vagy adnak vissza, magasabb rendű függvényeknek nevezzük. A legtöbb olyan nyelvben, ahol a függvények első osztályú értékek, vannak magasabb rendű függvények és lezárások is.

Nézzük meg például a következő Scheme függvényt:

; Visszaadja az összes olyan könyv listáját, amelyből legalább THRESHOLD példányt eladtak. (define (best-selling-books threshold) (filter (lambda (book) (>= (book-sales book) threshold)) book-list))

Ebben a példában a lambda kifejezés (lambda (könyv) (>= (könyv-értékesítés könyv) küszöbérték))) a legkelendőbb könyvek függvény része. A függvény futtatásakor a Scheme-nek a lambda értékét kell megtennie. Ezt úgy teszi, hogy létrehoz egy lezárást a lambda kódjával és egy hivatkozással a threshold változóra, amely egy szabad változó a lambdán belül. (A szabad változó egy olyan név, amely nincs értékhez kötve).

A szűrőfüggvény ezután lefuttatja a lezárást a listában szereplő minden egyes könyvre, hogy kiválassza, mely könyveket adja vissza. Mivel maga a zárlat rendelkezik a küszöbértékre való hivatkozással, a zárlat minden alkalommal használhatja ezt az értéket, amikor a filter futtatja a zárlatot. Maga a filter függvényt egy teljesen különálló fájlban lehet megírni.

Itt van ugyanez a példa átírva ECMAScript (JavaScript) nyelven, egy másik népszerű nyelven, amely támogatja a lezárásokat:

// Visszaadja az összes olyan könyv listáját, amelyből legalább a "küszöbérték" eladott példányszámot elérte. function bestSellingBooks(threshold) { return bookList. filter( function(book) { return book. sales >= threshold; }     ); }

Az ECMAScript itt a lambda helyett a function szót használja, a filter függvény helyett pedig az Array.filter metódust, de egyébként a kód ugyanazt a dolgot teszi ugyanúgy.

Egy függvény létrehozhat egy lezárást és visszaadhatja azt. A következő példa egy függvény, amely egy függvényt ad vissza.

A rendszerben:

; Adjon vissza egy függvényt, amely megközelíti az f deriváltját ; egy dx intervallum segítségével, amelynek megfelelően kicsinek kell lennie. (define (derivative f dx) (lambda (x) (/ (- (f (+ x dx))) (f x)) dx)))))

Az ECMAScript:

// Adjon vissza egy függvényt, amely megközelíti az f deriváltját // egy dx intervallummal, amelynek megfelelően kicsinek kell lennie. function derivative(f, dx) { return function(x) { return (f(x + dx) - f(x)) / dx; }; }; }

A zárókörnyezet megtartja az f és dx kötött változókat, miután a záró függvény (derivált) visszatér. A zártság nélküli nyelvekben ezek az értékek elvesznének a záró függvény visszatérése után. A zártsággal rendelkező nyelvekben a kötött változót mindaddig a memóriában kell tartani, amíg bármelyik zártság rendelkezik vele.

A lezárást nem kell névtelen függvényt használni. A Python programozási nyelv például csak korlátozottan támogatja az anonim függvényeket, de rendelkezik lezárásokkal. A fenti ECMAScript példa például a következő módon valósítható meg Pythonban:

# Adjon vissza egy függvényt, amely megközelíti az f # deriváltját egy dx intervallummal, amelynek megfelelően kicsinek kell lennie. def derivative(f, dx): def gradient(x): return (f(x + dx) - f(x)) / dx return gradiens

Ebben a példában a gradiens nevű függvény az f és dx változókkal együtt zárja le a függvényt. A külső, derivált nevű függvény ezt a zárlatot adja vissza. Ebben az esetben egy névtelen függvény is működne.

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

A Pythonban gyakran megnevezett függvényeket kell használni, mert a lambda-kifejezések csak más kifejezéseket (értéket visszaadó kódot) tartalmazhatnak, utasításokat (olyan kódot, amelynek hatása van, de nincs értéke) nem. Más nyelvekben, például a Scheme-ben azonban minden kód értéket ad vissza; a Scheme-ben minden kifejezés.

Zárások használata

A lezárásoknak számos felhasználási módja van:

  • A szoftverkönyvtárak tervezői lehetővé tehetik a felhasználók számára a viselkedés testreszabását azáltal, hogy lezárásokat adnak át argumentumként a fontos függvényeknek. Például egy értékeket rendező függvény elfogadhat egy olyan záró argumentumot, amely a rendezni kívánt értékeket egy felhasználó által meghatározott kritérium szerint hasonlítja össze.
  • Mivel a lezárások késleltetik a kiértékelést - azaz nem "csinálnak" semmit, amíg meg nem hívják őket -, vezérlési struktúrák definiálására használhatók. Például a Smalltalk összes szabványos vezérlési struktúrája, beleértve az elágazásokat (if/then/else) és a ciklusokat (while és for), olyan objektumok segítségével definiálható, amelyek metódusai elfogadják a lezárásokat. A felhasználók könnyen definiálhatják saját vezérlési struktúráikat is.
  • Több olyan függvény is előállítható, amelyek ugyanazt a környezetet zárják össze, lehetővé téve számukra a privát kommunikációt a környezet megváltoztatásával (olyan nyelveken, amelyek lehetővé teszik a hozzárendelést).

A rendszerben

(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)) ; nyomtat "none" (newline) (foo "meet me by the docks at midnight") (display (bar)) ; nyomtat "meet me by the docks at midnight"
  • A lezárások objektumrendszerek megvalósítására használhatók.

Megjegyzés: Egyes beszélők minden olyan adatszerkezetet, amely lexikális környezetet köt le, lezárásnak neveznek, de ez a kifejezés általában kifejezetten a függvényekre vonatkozik.

Kérdések és válaszok

K: Mi az a zárás az informatikában?


V: A zárlat egy olyan függvény, amely saját környezettel rendelkezik.

K: Mit tartalmaz egy zárlat környezete?


V: Egy zárlat környezete legalább egy kötött változót tartalmaz.

K: Ki adta a closure ötletének a nevét?


V: Peter J. Landin 1964-ben adta a closure ötletének a nevét.

K: Melyik programozási nyelv tette népszerűvé a lezárásokat 1975 után?


V: A Scheme programozási nyelv tette népszerűvé a lezárásokat 1975 után.

K: Az anonim függvények és a lezárások ugyanazok?


V: A névtelen függvényeket néha tévesen lezárásoknak nevezik, de nem minden névtelen függvény lezárás.

K: Mitől lesz egy névtelen függvény zárlat?


V: Egy névtelen függvény akkor zárlat, ha van saját környezete legalább egy kötött változóval.

K: Egy névvel ellátott zárlat névtelen?


V: Nem, a megnevezett zárlat nem névtelen.

AlegsaOnline.com - 2020 / 2023 - License CC3