Frage

Könnte sich das jemand erklären?Ich verstehe die grundlegenden Konzepte hinter Ihnen, aber ich sehe Häufig, dass Sie austauschbar verwendet und ich verwirrt.

Und jetzt sind wir hier, wie unterscheiden Sie sich von einer regulären Funktion?

War es hilfreich?

Lösung

A Lambda ist nur eine anonyme Funktion - eine Funktion ohne Namen definiert. In einigen Sprachen wie Scheme, sind sie benannten Funktionen gleichwertig. In der Tat ist die Funktionsdefinition neu geschrieben intern eine Lambda auf eine Variable als verbindlich. In anderen Sprachen wie Python, gibt es einige (eher unnötig) Unterschiede zwischen ihnen, aber sie verhalten sich die gleiche Art und Weise anders.

A Verschluss ist eine beliebige Funktion, die schließt sich über die Umgebung , in der sie definiert wurde. Dies bedeutet, dass es Variablen, die nicht in seiner Parameterliste zugreifen kann. Beispiele:

def func(): return h
def anotherfunc(h):
   return func()

Dies wird einen Fehler verursachen, weil func nicht schließen über , um die Umwelt in anotherfunc - h nicht definiert ist. func schließt nur über die globale Umwelt. Dies funktioniert:

def anotherfunc(h):
    def func(): return h
    return func()

Denn hier wird func in anotherfunc definiert und in Python 2.3 und höher (oder eine Zahl wie diese), wenn sie fast got Verschlüsse korrekt (Mutation noch nicht funktioniert), bedeutet dies, dass es schließt über anotherfunc Umgebung und Variablen innerhalb der darauf zugreifen kann. In Python 3.1+ arbeitet Mutation auch wenn das nonlocal Stichwort mit .

Ein weiterer wichtiger Punkt - func wird weiterhin auch anotherfunc Umwelt schließen über, wenn es nicht mehr in anotherfunc ausgewertet. Dieser Code wird auch funktionieren:

def anotherfunc(h):
    def func(): return h
    return func

print anotherfunc(10)()

Dies wird 10 drucken.

Dies ist, wie Sie feststellen, hat nichts mit Lambda s zu tun -. Sie sind zwei verschiedene (wenn auch verwandte) Konzepte

Andere Tipps

Es gibt eine Menge Verwirrung um lambdas und Verschlüsse, auch in den Antworten auf diese Frage Stackoverflow hier. Stattdessen Zufalls Programmierer fragen, die über Verschlüsse aus der Praxis mit bestimmten Programmiersprachen oder andere ahnungslose Programmierer gelernt, nehmen Sie eine Reise in die source (wo alles begann). Und da lambdas und Schließungen kommen aus Lambda-Kalkül erfunden von Alonzo Church zurück in den 30er Jahren vor der ersten elektronischen Computer überhaupt existiert, ist dies die source ich rede.

Lambda-Kalküls ist die einfachste Programmiersprache der Welt. Die einzigen Dinge, die Sie in es tun: ►

  • ANWENDUNG: Anwenden eines Ausdrucks zu einem anderen, bezeichnet f x
    (Denken Sie daran, als Funktionsaufruf , wobei f ist die Funktion und x ist einzigen Parameter)
  • .
  • ABSTRACTION: Wird ein Symbol in einem Ausdruck auftreten, zu markieren, dass dieses Symbol nur ein „Slot“ ist, wartet ein leeres Feld mit dem Wert gefüllt zu werden, eine „Variable“ wie es war. Es wird durch das Voranstellen eines griechischen Buchstaben λ (Lambda), dann den symbolischen Namen (z x), dann einen Punkt . vor dem Ausdruck getan. Dieser wandelt dann den Ausdruck in eine Funktion erwartet eine Parameter
    . Zum Beispiel: λx.x+2 nimmt den Ausdruck x+2 und sagt, dass das Symbol x in diesem Ausdruck ist ein gebunden Variable -. es kann mit einem Wert, den Sie als Parameter liefern ersetzt werden
    Beachten Sie, dass die Funktion auf diese Weise definiert ist anonym - es keinen Namen hat, so dass Sie noch nicht darauf verweisen können, aber Sie können sofort anrufen es (nicht vergessen Anwendung) durch den Parameter liefert es wartet, wie folgt aus:? (λx.x+2) 7. Dann wird der Ausdruck (in diesem Fall eine wörtliche Wert) 7 als x im subexpression x+2 der angelegten Lambda substituiert ist, so erhalten Sie 7+2, die dann durch eine gemeinsame arithmetics Regeln 9 reduziert.

So haben wir eines der Rätsel gelöst:
Lambda ist die anonyme Funktion aus dem obigen Beispiel, λx.x+2.


In verschiedenen Programmiersprachen kann die Syntax für funktionelle Abstraktion (lambda) unterscheiden. Zum Beispiel in JavaScript sieht es wie folgt aus:

function(x) { return x+2; }

und Sie können sofort anwenden, um einige Parameter wie folgt aus:

(function(x) { return x+2; })(7)

oder Sie können diese anonyme Funktion speichern (Lambda) in eine Variable:

var f = function(x) { return x+2; }

, die es effektiv einen Namen f gibt, so dass Sie sich darauf beziehen und nennen es später mehrmals, z.

alert(  f(7) + f(10)  );   // should print 21 in the message box

Aber man muß es nicht nennen. Man könnte es sofort:

alert(  function(x) { return x+2; } (7)  );  // should print 9 in the message box

In LISP, Lambda-Ausdrücke sind wie folgt aus:

(lambda (x) (+ x 2))

und Sie können eine solche Lambda aufrufen, indem er sofort auf einen Parameter der Anwendung:

(  (lambda (x) (+ x 2))  7  )


OK, jetzt ist es Zeit, das andere Rätsel zu lösen: was für ein ist Schließung . Um das zu tun, lassen Sie uns darüber reden, Symbole ( Variablen ) in Lambda-Ausdrücke.

Wie gesagt, was die Lambda-Abstraktion tut, ist Bindung ein Symbol in seiner subexpression, so dass es ein substitutible Parameter . Ein solches Symbol genannt wird gebunden . Aber was, wenn es andere Symbole im Ausdruck? Zum Beispiel: λx.x/y+2. In diesem Ausdruck ist das Symbol x durch die Lambda-Abstraktion λx. gebunden vorhergehenden davon. Aber das andere Symbol, y, nicht gebunden ist - es ist kostenlos . Wir wissen nicht, was es ist und woher es kommt, so dass wir nicht wissen, was es Hilfe und was Wert es repräsentiert, und deshalb können wir nicht, dass die Expression bewerten bis wir FigurSie heraus, was y Mittel.

In der Tat, das gleiche gilt mit den beiden anderen Symbole, 2 und +. Es ist nur so, dass wir so vertraut mit diesen beiden Symbole sind, die wir in der Regel vergessen, dass der Computer sie nicht kennt, und wir brauchen es zu sagen, was sie bedeuten, indem sie irgendwo definieren, zum Beispiel in einer Bibliothek oder die Sprache selbst.

Sie können denken Sie an den kostenlos Symbole als irgendwo anders definiert, außerhalb des Ausdrucks, in seinem „umgebenden Kontext“, der seine genannt Umwelt . Die Umwelt könnte ein größerer Ausdruck sein, dass dieser Ausdruck ist ein Teil (wie Qui-Gon Jinn sagte: „Es gibt immer einen größeren Fisch“;)) oder in einer Bibliothek oder in der Sprache selbst (als primitiven ).

Auf diese Weise können wir Lambda-Ausdrücke in zwei Kategorien unterteilen:

  • CLOSED Ausdrücke: Jedes Symbol, das in dieser Ausdrücken auftritt, ist gebunden durch eine Lambda-Abstraktion. Mit anderen Worten, sie sind self-contained ; sie benötigen keinen umgebenden Kontext bewertet werden. Sie werden auch als combinators .
  • OPEN Ausdrücke: einige Symbole in dieser Ausdrücke sind nicht gebunden - das heißt, einige der Symbole in ihnen vorkommenden sind kostenlos und sie erfordern eine externe Informationen und damit sie kann nicht ausgewertet werden, bis Sie die Definitionen dieser Symbole liefern.

Sie können ein SCHLIEßEN open Lambda-Ausdruck durch die Umwelt Versorgung , die durch all diese frei Symbole definiert sie auf einige Werte Bindung (die Zahlen sein können, Streichern, anonym Funktionen aka lambdas, was auch immer ...).

Und hier kommt die Schließung Teil:
Die Schließung a Lambda-Ausdruck ist diese besondere Gruppe von Symbolen in dem äußeren Rahmen (Umwelt) definiert, die Werte für die freien Symbole geben in diesem Ausdruck, so dass sie nicht mehr frei zu machen. Es stellt sich ein offen Lambda-Ausdruck, der noch einige „undefiniert“ freie Symbole enthält, in eine geschlossen ein, die nicht mehr alle freien Symbole hat.

Zum Beispiel, wenn Sie den folgenden Lambda-Ausdruck haben: λx.x/y+2 wird das Symbol x gebunden, während das Symbol y frei ist, deshalb ist der Ausdruck open und nicht ausgewertet werden kann, es sei denn, Sie sagen, was Mittel y (und das gleiche mit + und 2, die auch frei sind). Aber nehmen wir an, dass Sie auch eine Umwelt wie folgt aus:

{  y: 3,
+: [built-in addition],
2: [built-in number],
q: 42,
w: 5  }

Das Umwelt liefert Definitionen für alle "undefiniert" (frei) Symbole aus unserer Lambda-Ausdruck (y, +, 2) und mehrere zusätzliche Symbole (q, w). Die Symbole, die wir brauchen, zu definieren sind diese Teilmenge der Umwelt:

{  y: 3,
+: [built-in addition],
2: [built-in number]  }

und das ist genau die Schließung unseres Lambda-Ausdruck:>

Mit anderen Worten, es schließt ein offener Lambda-Ausdruck. Dies ist, wo der Name Schließung von in erster Linie kam, und das ist, warum so viele Menschen der Antworten in diesem Thread nicht ganz richtig: P


Warum sind sie falsch? Warum haben so viele von ihnen sagen, dass Verschlüsse einige Datenstrukturen im Speicher sind, oder einige Funktionen der Sprache, die sie verwenden, oder warum nicht zu verwechseln sie Verschlüsse mit Lambda-Ausdrücke? : P

Nun, die Corporate marketoids von Sun / Oracle, Microsoft, Google usw. ist schuld, denn das ist, was sie diese Konstrukte in ihrer Sprache (Java, C #, Go usw.) genannt. Sie nennen oft „Verschlüsse“, was angeblich nur lambda sein. Oder sie rufen „Verschlüsse“ eine besondere Technik, die sie verwendeten lexikalischen Scoping zu implementieren, das heißt, die Tatsache, dass eine Funktion kann die Variablen zugreifen, die in seinem äußeren Umfang zum Zeitpunkt ihrer Definition definiert wurden. Sie sagen oft that die Funktion „umschließt“ diese Variablen, das heißt, fängt sie in Struktur einige Daten, um sie davor zu bewahren, nachdem die Ausführung beendet die äußere Funktion zerstört. Aber dies ist nur hergerichtete post factum „Folklore Etymologie“ und Marketing, das einzige, was noch verwirrender macht, weil jede Sprache Anbieter seine eigene Terminologie verwendet wird.

Und es ist noch schlimmer, weil die Tatsache, dass es immer ein bisschen Wahrheit in dem, was sie sagen, was du nicht einfach erlaubt es abtun als falsch: P Lassen Sie mich erklären:

Wenn Sie eine Sprache implementieren möchten, die Lambda-Ausdrücke als Bürger erste Klasse verwendet, müssen Sie, damit sie Symbole in der sie umgebenden Kontext definiert verwenden (das heißt, freie Variablen in Ihrem lambda zu verwenden). Und diese Symbole muss es auch sein, wenn die umgebende Funktion zurückgibt. Das Problem ist, dass diese Symbole zu einem gewissen lokalen Speicher der Funktion (in der Regel auf den Call-Stack) gebunden sind, die dort nicht mehr sein wird, wenn die Funktion zurückkehrt. Daher ist für eine Lambda erwarten, um die Art und Weise Sie zu arbeiten, müssen Sie irgendwie „erfassen“, alle diese freien Variablen von ihrem äußeren Rahmen und speichern Sie sie für später, auch wenn der äußere Rahmen wird verschwunden sein. Das heißt, Sie müssen die Schließung Ihrer Lambda (alle diese externen Variablen verwendet er) finden und speichern Sie es woanders (entweder durch Erstellen einer Kopie oder durch Raum für deren Herstellung im Voraus, woanders als auf dem Stapel). Die eigentliche Methode, dieses Ziel zu erreichen, verwenden eine „Implementierungsdetail“ Ihrer Sprache. Was hier wichtig ist, ist die Schließung , das ist der Satz von freien Variablen von der Umwelt Ihr Lambda, die irgendwo gespeichert werden müssen.

Es dauerte dauerte nicht zu lange für die Menschen die eigentliche Datenstruktur starten sie in ihrer Sprache der Implementierungen verwenden Aufruf Schließung als „Verschluss“ selbst zu implementieren. Die Struktur in der Regel sieht ungefähr wie folgt aus:

Closure {
   [pointer to the lambda function's machine code],
   [pointer to the lambda function's environment]
}

und diese Datenstrukturen werden als Parameter an anderen Funktionen übergeben um, kehrten von Funktionen und gespeicherte Variablen, Lambda-Ausdrücke darzustellen, und so dass sie ihre einschließenden Umgebung sowie den Maschinencode für den Zugriff auf in diesem Zusammenhang laufen. Aber es ist nur ein Weg (einer von vielen) zu implementieren Verschluss, nicht die Verschluss selbst.

Wie ich oben erläutert, ist die Schließung einer Lambda-Ausdruck der Untergruppe von Definitionen in seiner Umgebung ist, die in diesem Lambda-Ausdruck enthaltenen Werte zu den freien Variablen geben, effektiv Schließen der Ausdruck (ein Drehen < em> offen Lambda-Ausdruck, der noch werden nicht ausgewertet, in ein geschlossen Lambda-Ausdruck, der kann dann ausgewertet werden, da alle darin enthaltenen Symbole nun definiert sind).

Alles andere ist nur ein „Cargo-Kult“ und „voo-doo Magie“ von Programmierern und Sprache Distributoren keine Ahnung von den wahren Wurzeln dieser Begriffe.

Ich hoffe, dass Ihre Fragen beantwortet. Aber wenn Sie die Follow-up-Fragen haben, fühlen sich frei, um sie in den Kommentaren zu fragen, und ich werde versuchen, es besser zu erklären.

Wenn die meisten Leute denken Funktionen, denken Sie benannte Funktionen:

function foo() { return "This string is returned from the 'foo' function"; }

Diese werden beim Namen genannt, natürlich:

foo(); //returns the string above

Mit lambda-Ausdrücke, Sie können anonyme Funktionen:

 @foo = lambda() {return "This is returned from a function without a name";}

Mit dem obigen Beispiel können Sie rufen Sie die lambda-durch die variable zugewiesen wurde:

foo();

Nützlicher als die Zuordnung anonymer Funktionen Variablen sind jedoch vorbei zu oder von höherer Ordnung Funktionen, D. H. Funktionen, die akzeptieren/Rückkehr andere Funktionen.In vielen dieser Fälle, die Benennung einer Funktion ist nicht notwendiger:

function filter(list, predicate) 
 { @filteredList = [];
   for-each (@x in list) if (predicate(x)) filteredList.add(x);
   return filteredList;
 }

//filter for even numbers
filter([0,1,2,3,4,5,6], lambda(x) {return (x mod 2 == 0)}); 

Ein Verschluss kann eine mit oder ohne Namen anonyme Funktion, aber ist so wie wir es kennen, wenn es "schließt über" Variablen in den Bereich, wo die Funktion definiert ist, d.h., der Verschluss immer noch auf die Umgebung, mit der äußeren Variablen, die in den Verschluss selbst.Hier ist eine benannte Verschluss:

@x = 0;

function incrementX() { x = x + 1;}

incrementX(); // x now equals 1

Das scheint nicht wie viel, aber was, wenn das alles war in einer anderen Funktion und die Sie übergeben incrementX um eine externe Funktion?

function foo()
 { @x = 0;

   function incrementX() 
    { x = x + 1;
      return x;
    }

   return incrementX;
 }

@y = foo(); // y = closure of incrementX over foo.x
y(); //returns 1 (y.x == 0 + 1)
y(); //returns 2 (y.x == 1 + 1)

Dies ist, wie man statusbehaftete Objekte in die funktionale Programmierung.Seit der Benennung "incrementX" ist nicht notwendig, Sie können eine lambda-in diesem Fall:

function foo()
 { @x = 0;

   return lambda() 
           { x = x + 1;
             return x;
           };
 }

Nicht alle Verschlüsse sind lambdas und nicht alle Lambdas sind Verschlüsse. Beide sind Funktionen, aber nicht unbedingt in der Art und Weise sind wir verwendet, um zu wissen.

Eine Lambda ist im Wesentlichen eine Funktion, die als die Standardmethode deklarieren Funktionen Inline eher definiert ist. Lambda-Ausdrücke können häufig herumgereicht als Objekte werden.

Ein Verschluß ist eine Funktion, die durch Bezugnahme auf Feldern außerhalb seines Körper seines umgebenden Zustand umschließt. Der geschlossene Zustand bleibt über Anrufungen des Verschlusses.

In einer objektorientierten Sprache, Verschlüsse werden in der Regel durch Objekte zur Verfügung gestellt. Allerdings implementieren einige OO-Sprachen (zB C #) spezielle Funktionalität, die von rein bereitgestellt näher an der Definition von Verschlüssen ist funktionale Sprachen (wie Lispeln), den Staat keine Objekte umschließen.

Was interessant ist, dass die Einführung von Lambdas und Closures in C # bringt funktionale Programmierung näher an Mainstream-Nutzung.

Es ist so einfach: Lambda ist ein Sprachkonstrukt, das heißt einfach Syntax für anonyme Funktionen; ein Verschluss ist eine Technik, sie umzusetzen -. oder keine erstklassigen Funktionen, was das betrifft, mit dem Namen oder anonym

Genauer gesagt, ein Verschluss ist, wie ein First-Class-Funktion zur Laufzeit dargestellt wird, , als ein Paar von seinem „Code“ und eine Umgebung „Schließen“ über alle nichtlokalen in diesem Code verwendeten Variablen. Auf diese Weise sind diese Variablen noch verfügbar, wenn auch die äußeren Bereiche, wo sie ihren Ursprung bereits verlassen wurde.

Leider gibt es viele Sprachen gibt, die nicht unterstützen Funktionen als erstklassige Werte, oder sie nur in verkrüppelte Form unterstützen. So oft Menschen den Begriff "Verschluss" verwenden zu unterscheiden "the real thing".

Aus der Sicht von Programmiersprachen, sind sie völlig zwei verschiedene Dinge.

Im Grunde genommen für eine Turing kompletten Sprache, die wir benötigen nur sehr begrenzte Elemente, z.B. Abstraktion, Anwendung und Reduktion. Abstraktion und Anwendung bietet die Möglichkeit, Sie lamdba Ausdruck aufbauen kann, und Reduktion dertermines die Bedeutung des Lambda-Ausdruck.

Lambda bietet eine Möglichkeit, Sie abstrahieren kann der Berechnungsprozess aus. beispielsweise die Summe von zwei Zahlen zu berechnen, ein Verfahren, das zwei Parameter x, y und kehren nimmt x + y abstrahiert werden kann. In Schema können Sie schreiben Sie es als

(lambda (x y) (+ x y))

Sie können die Parameter umbenennen, aber die Aufgabe, die sie sich nicht ändert abgeschlossen ist. In fast allen Programmiersprachen, können Sie den Lambda-Ausdruck einen Namen geben, die Funktionen genannt werden. Aber es kein großer Unterschied ist, können sie vom Konzept her als nur Syntax Zucker in Betracht gezogen werden.

OK, jetzt vorstellen, wie diese umgesetzt werden können. Jedes Mal, wenn wir den Lambda-Ausdruck auf einige Ausdrücke gelten, z.

((lambda (x y) (+ x y)) 2 3)

Wir können einfach die Parameter mit dem Ausdruck ersetzen ausgewertet werden. Dieses Modell ist bereits sehr mächtig. Aber dieses Modell nicht ermöglicht uns die Werte der Symbole zu ändern, z.B. Wir können nicht die Statusänderung imitieren. Wir brauchen also ein komplexeres Modell. Um es kurz zu machen, wenn wir die Bedeutung des Lambda-Ausdruck berechnen wollen, setzen wir das Paar von Symbol und dem entsprechenden Wert in einer Umgebung (oder Tabelle). Dann wird der Rest (x + y) durch Nachschlagen der entsprechenden Symbole in der Tabelle bewertet. Nun, wenn wir einige Grundelemente sorgen für die Umwelt direkt zu bedienen, können wir die Änderungen des Status modellieren!

Vor diesem Hintergrund überprüfen Sie diese Funktion:

(lambda (x y) (+ x y z))

Wir wissen, dass, wenn wir den Lambda-Ausdruck, x y bewerten wird in einem neuen Tabelle gebunden werden. Aber wie und wo können wir uns z up? Eigentlich ist z eine freie Variable genannt. Es muss eine Außen sein eine Umgebung, die z enthält. Andernfalls ist die Bedeutung des Ausdrucks kann nicht nur durch die Bindung x und y bestimmt werden. Um dies deutlich zu machen, können Sie etwas wie folgt in Schema schreiben:

((lambda (z) (lambda (x y) (+ x y z))) 1)

So z würde zu 1 in einer äußeren Tabelle gebunden werden. Wir bekommen immer noch eine Funktion, die zwei Parameter akzeptiert, aber die wahre Bedeutung der es hängt auch von der äußeren Umgebung. Mit anderen Worten schließt die äußere Umgebung auf die freien Variablen. Mit Hilfe von Set !, können wir die Funktion Stateful machen, das heißt, es ist keine Funktion im Sinne der Mathematik. Was es nicht nur zurückgibt, hängt von der Eingabe, sondern z als auch.

Das ist etwas, das man schon sehr gut kennen, fast ein Verfahren von Objekten beruht immer auf dem Zustand der Objekte. Das ist, warum manche Leute sagen, „Verschlüsse sind Objekte des armen Mannes.“ Aber wir könnten auch Objekte als Arme-Leute-Verschlüsse, da wir wirklich wie First-Class-Funktionen betrachten.

Ich benutze Schema die Ideen zu veranschaulichen aufgrund dieser Regelung ist eine der frühesten Sprache, die realen Schließungen hat. Alle hier Materialien sind viel besser in SICP Kapitel vorgestellt 3.

Um es zusammenzufassen, Lambda und Schließung sind wirklich unterschiedliche Konzepte. Eine Lambda ist eine Funktion. Ein Verschluß ist ein Paar von Lambda und die entsprechenden Umgebung, die das Lambda-schließt.

Konzept ist das gleiche, wie oben beschrieben, aber wenn man von PHP Hintergrund ist, diese weiter erklären PHP-Code.

$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, function ($v) { return $v > 2; });

function ($ v) {return $ v> 2; } Ist die Lambda-Funktionsdefinition. Wir können es auch speichern, in einer Variablen, so kann es sein, wiederverwendbar:

$max = function ($v) { return $v > 2; };

$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max);

Nun, was ist, wenn Sie die zulässige maximale Anzahl in der gefilterten Array ändern möchten? Sie müßten eine weitere Lambda-Funktion schreiben oder einen Verschluss (PHP 5.3) erstellen:

$max_comp = function ($max) {
  return function ($v) use ($max) { return $v > $max; };
};

$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max_comp(2));

Eine Schließung ist eine Funktion, die in ihrer eigenen Umgebung ausgewertet wird, die eine oder mehrere gebundene Variablen hat, auf die zugegriffen werden kann, wenn die Funktion aufgerufen wird. Sie stammen aus der funktionalen Programmierung Welt, wo es eine Reihe von Konzepten im Spiel ist. Verschlüsse sind wie Lambda-Funktionen, aber schlauer in dem Sinne, dass sie die Fähigkeit haben, mit Variablen von der äußeren Umgebung der zu interagieren, wo der Verschluss definiert ist.

Hier ist ein einfacheres Beispiel für PHP-Verschluss:

$string = "Hello World!";
$closure = function() use ($string) { echo $string; };

$closure();

Schön in diesem Artikel erläutert.

Diese Frage ist alt und bekam viele Antworten. Jetzt mit Java 8 und Offizielle Lambda, die nicht offizielle Schließung Projekte sind belebt sie die Frage.

Die Antwort in Zusammenhang mit Java (über Lambdas und Schließungen - was ist das Differenz ):

  

"Eine Schließung ist ein Lambda-Ausdruck mit einer Umgebung gepaart, die jedem seiner freien Variablen auf einen Wert bindet. In Java, Lambda-Ausdrücke werden durch Schließungen umgesetzt werden, so dass die beiden Begriffe gekommen sind austauschbar in die verwendet werden Gemeinschaft. "

Einfach gesagt, Verschluss ein Trick über Umfang ist, Lambda ist eine anonyme Funktion. Wir können erkennen, Verschluss mit Lambda-eleganten und Lambda oft als auf eine höhere Funktion übergebenen Parameter verwendet wird

Ein Lambda-Ausdruck ist nur eine anonyme Funktion. im Klar java, zum Beispiel, können Sie es wie folgt schreiben können:

Function<Person, Job> mapPersonToJob = new Function<Person, Job>() {
    public Job apply(Person person) {
        Job job = new Job(person.getPersonId(), person.getJobDescription());
        return job;
    }
};

, wo die Klasse Funktion nur in Java-Code erstellt wird. Jetzt können Sie mapPersonToJob.apply(person) irgendwo anrufen, es zu benutzen. das ist nur ein Beispiel. Das ist eine Lambda bevor es Syntax für sie war. Lambdas eine Abkürzung für diese.

Verschluss:

ein Lambda wird zu einem Verschluss, wenn es um die Variablen außerhalb dieses Umfangs zugreifen kann. Ich denke, man seine Magie sagen kann, sie auf magische Weise um die Umwelt wickeln kann es erstellt wurde und verwenden Sie die Variablen außerhalb des Anwendungsbereichs (äußeren Umfang. so klar zu sein, ein Verschlussmittel ein Lambda seine OUTER SCOPE zugreifen kann.

in Kotlin kann eine Lambda immer Zugriff auf seine Schließung (die Variablen, die in seinem äußeren Umfang sind)

Es hängt davon ab, ob eine Funktion externe Variable verwendet oder nicht Operation auszuführen.

Externe Variablen -. Variablen außerhalb des Rahmens einer Funktion definiert

  • Lambda-Ausdrücke sind staatenlos , weil es auf Parameter, interne Variablen oder Konstanten hängt Operationen auszuführen.

    Function<Integer,Integer> lambda = t -> {
        int n = 2
        return t * n 
    }
    
  • Verschlüsse Haltezustand , weil es externe Variablen (d.h. variable außerhalb des Umfangs des Funktionskörpers definiert) verwendet, zusammen mit Parametern und Konstanten Operationen durchzuführen.

    int n = 2
    
    Function<Integer,Integer> closure = t -> {
        return t * n 
    }
    

Wenn Java-Verschluss schafft, es hält die Variable n mit der Funktion, so kann es referenziert werden, wenn überall auf andere Funktionen oder verwendet geben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top