Lezárás (programozás)

Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt hozzászólók, és jelentősen eltérhet a 2015. február 19-én felülvizsgált verziótól ; az ellenőrzések 29 szerkesztést igényelnek .

A programozásban a zárás ( ang.  closure ) egy első osztályú függvény , amelynek törzsében hivatkozások találhatók a környező kódban a függvény törzsén kívül deklarált változókra, amelyek nem a paraméterei. Egy másik nyelvben a lezárás olyan függvény, amely a hatókörében lévő szabad változókra hivatkozik .

A lezárás, akárcsak az objektumpéldány , a funkcionalitás és az adatok egymáshoz kötött és csomagolt ábrázolásának módja.

A zárás egy speciális funkció. Egy másik függvény törzsében van meghatározva, és minden végrehajtáskor létrejön. Szintaktikailag ez egy olyan funkciónak tűnik, amely teljes egészében egy másik funkció testén belül van. Ebben az esetben a beágyazott belső függvény hivatkozásokat tartalmaz a külső függvény helyi változóira. Minden alkalommal, amikor a külső függvény végrehajtódik, a belső függvény új példánya jön létre, új hivatkozásokkal a külső függvény változóira.

Lezárás esetén a külső függvény változóira való hivatkozások mindaddig érvényesek a beágyazott függvényen belül, amíg a beágyazott függvény fut , még akkor is, ha a külső függvény futása befejeződött, és a változók kikerültek a hatókörből. [egy]

A lezárás egy függvény kódját a lexikális környezetéhez kapcsolja (az a hely, ahol a kódban definiálva van). A lexikális záróváltozók abban különböznek a globális változóktól, hogy nem foglalják el a globális névteret. Abban különböznek az objektumok változóitól, hogy nem objektumokhoz, hanem függvényekhez vannak kötve.

Példák

További példákért lásd a wikikönyvet.

A séma nyelvén

( define ( make-adder n ) ; zárt lambda kifejezést ad vissza ( lambda ( x ) ; ahol x egy kötött változó, ( + x n ) ; és n egy szabad (külső kontextusból fogva ) ) ( define add1 ( make-adder 1 )) ; végezze el az 1 hozzáadásának eljárását ( add1 10 ) ; hívd, 11-et tér vissza ( define sub1 ( make-adder -1 )) ; végezzen el egy eljárást az 1 ( al1 10 ) kivonására ; hívd, 9-et ad vissza

JavaScriptben [ 2]

„szigorúan használjon” ; const add = függvény ( x ) { return függvény ( y ) { const z = x + y ; konzol . log ( x + '+' + y + '=' + z ); visszatér z ; }; }; const res = add ( 3 )( 6 ); // 9-et ad vissza, és 3+6=9-et ír ki a konzolra konzol . log ( res );

Ugyanez a kód az ECMAScript2015 verzióban "nyíl függvények" használatával:

„szigorúan használjon” ; const add = x => y => { const z = x + y ; konzol . log ( x + '+' + y + '=' + z ); visszatér z ; }; const res = add ( 3 )( 6 ); // 9-et ad vissza, és 3+6=9-et ír ki a konzolra konzol . log ( res );

Magyarázat: JavaScriptben az => kombináció egy nyílfüggvény-deklarációs operátor, lásd például: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions . Itt az állandó összeadás az x argumentum függvénye kerül elhelyezésre , melynek eredménye egy másik függvény lesz, mégpedig az y argumentum függvénye , aminek az eredményét a zárójelben megadott kódblokk számítja ki. Ez a kódblokk függvényének y argumentumára és a külső függvény x argumentumára létrehozott lezárásra támaszkodik .

Az add(3)(6) meghívásakor az add változóban tárolt függvény 3-as argumentummal kerül meghívásra, és a 3 - as értékhez kötött függvényt adja vissza x zárásában .

Továbbá egy ilyen hívás keretein belül ez a függvény y = 6 argumentummal hajtódik végre, és 9 -et ad vissza .

Rekurzív lezárást végezhet :

„szigorúan használjon” ; const add = x => y => { const z = x + y ; konzol . log ( x + '+' + y + '=' + z ); return add ( z ); }; const res = add ( 1 )( 4 )( 6 )( 9 ); konzol . log ( res ); /* 1+4=5 5+6=11 11+9=20 [Funkció]*/

Amikor a JS-kód fut, a helyi változók a hatókörben tárolódnak. A JavaScriptben a lokális változók akkor is megmaradhatnak a memóriában, ha a függvény értéket adott vissza.

A JavaScriptben minden függvény lezárás, vagyis amikor egy függvényt létrehozunk, mindig létrejön egy lezárás, bár gyakran üres, mivel a függvények általában nem használnak semmit a kontextus deklarációjából. De meg kell értenie a különbséget a lezárás létrehozása és az új hatókör objektum létrehozása között: a lezárás (függvény + hivatkozás az aktuális hatóköri láncra) akkor jön létre, amikor a függvény definiálva van, de egy új hatókör objektum jön létre (és a módosításra használják). a zárás hatóköri lánca) minden függvényhíváskor.

PHP -ben

A PHP-ben a lezárások névtelen függvények , speciális konstrukciók, amelyek lehetővé teszik olyan függvények leírását, amelyeknek nincs konkrét neve.

<?php function add ( $x ) { return function ( $y ) use ( $x ) { // <-- anonymous function (zárás) return $x + $y ; }; // <-- ide kell ez a pontosvessző! } echo add ( 3 ) ( 5 ) . PHP_EOL ; // Kimenet: 8 $f = összeadás ( 3 ); var_dump ( $f ); // Kimenet: object(Closure) echo $f ( 6 ) . PHP_EOL ; // Kimenet: 9

A PHP-ben a változók a szülő hatókörből öröklődnek a use konstrukcióval , az örökölt változók nevének explicit megadásával.

Egy másik példa a lezárás átadására egy olyan metódushoz, ahol hívható paramétert várnak el:

<?php function power ( $arr , $exp ) { // A $func a zárásunkat leíró Closure objektumra való hivatkozást tárolja $func = function ( $el ) use ( $exp ) { return $el ** $exp ; }; return array_map ( $func , $arr ); } $lista = [ 1 , 3 , 4 ]; var_dump ( power ( $lista , 2 )); // Kimenet: array(3) {[0]=>int(1) [1]=>int(9) [2]=>int(16)} var_dump ( power ( $list , 3 )); // Kimenet: array(3) {[0]=>int(1) [1]=>int(27) [2]=>int(64)}


Lásd még

Jegyzetek

  1. A blokkok lehetnek lezárások – konténerek, blokkok és iterátorok – Ruby programozása. A Pragmatikus programozói kézikönyv. . Letöltve: 2011. szeptember 29. Az eredetiből archiválva : 2011. szeptember 23..
  2. Lezárás: Funkciólezárások és adatok tárolása a funkció hatókörében . — 2018-01-08. Az eredetiből archiválva : 2019. november 29.