Kann mir das jemand erklären? Ich verstehe die grundlegenden Konzepte dahinter, aber ich sehe oft, dass sie austauschbar verwendet werden, und das verwirrt mich.
Und wenn wir schon dabei sind, wie unterscheiden sie sich von einer normalen Funktion?
Kann mir das jemand erklären? Ich verstehe die grundlegenden Konzepte dahinter, aber ich sehe oft, dass sie austauschbar verwendet werden, und das verwirrt mich.
Und wenn wir schon dabei sind, wie unterscheiden sie sich von einer normalen Funktion?
Aus der Sicht der Programmiersprachen handelt es sich um zwei völlig unterschiedliche Dinge.
Für eine vollständige Turing-Sprache benötigen wir im Grunde nur sehr wenige Elemente, z.B. Abstraktion, Anwendung und Reduktion. Abstraktion und Anwendung ermöglichen den Aufbau von Lambda-Ausdrücken, während die Reduktion die Bedeutung der Lambda-Ausdrücke ableitet.
Lambda bietet eine Möglichkeit, den Berechnungsprozess zu abstrahieren. Um beispielsweise die Summe zweier Zahlen zu berechnen, kann ein Prozess, der zwei Parameter x, y annimmt und x+y zurückgibt, abstrahiert werden. In einem Schema kann man das wie folgt schreiben
(lambda (x y) (+ x y))
Sie können die Parameter umbenennen, aber die Aufgabe, die sie erfüllt, ändert sich nicht. In fast allen Programmiersprachen kann man dem Lambda-Ausdruck einen Namen geben, der dann als Funktion bezeichnet wird. Aber es gibt keinen großen Unterschied, sie können konzeptionell als reiner Syntaxzucker betrachtet werden.
OK, jetzt stellen Sie sich vor, wie das umgesetzt werden kann. Wann immer wir den Lambda-Ausdruck auf einige Ausdrücke anwenden, z.B.
((lambda (x y) (+ x y)) 2 3)
Wir können die Parameter einfach durch den zu bewertenden Ausdruck ersetzen. Dieses Modell ist bereits sehr leistungsfähig. Aber dieses Modell ermöglicht es uns nicht, die Werte von Symbolen zu ändern, z.B. können wir die Änderung des Status nicht nachahmen. Wir brauchen also ein komplexeres Modell. Um es kurz zu machen, immer wenn wir die Bedeutung des Lambda-Ausdrucks berechnen wollen, legen wir das Paar aus Symbol und dem entsprechenden Wert in eine Umgebung (oder Tabelle). Dann wird der Rest (+ x y) durch Nachschlagen der entsprechenden Symbole in der Tabelle ausgewertet. Wenn wir nun einige Primitive zur Verfügung stellen, um direkt mit der Umgebung zu arbeiten, können wir die Statusänderungen modellieren!
Vor diesem Hintergrund sollten Sie diese Funktion überprüfen:
(lambda (x y) (+ x y z))
Wir wissen, dass, wenn wir den Lambda-Ausdruck auswerten, x und y in eine neue Tabelle gebunden werden. Aber wie und wo können wir z nachschlagen? Eigentlich ist z eine freie Variable. Es muss eine äußere eine Umgebung geben, die z enthält. Andernfalls kann die Bedeutung des Ausdrucks nicht allein durch die Bindung von x und y bestimmt werden. Um dies zu verdeutlichen, können Sie etwas wie folgt in Schema schreiben:
((lambda (z) (lambda (x y) (+ x y z))) 1)
In einer äußeren Tabelle würde z also an 1 gebunden sein. Wir erhalten immer noch eine Funktion, die zwei Parameter akzeptiert, aber die tatsächliche Bedeutung hängt auch von der äußeren Umgebung ab. Mit anderen Worten: Die äußere Umgebung schließt die freien Variablen ein. Mit Hilfe von set! können wir die Funktion zustandsabhängig machen, d. h. sie ist keine Funktion im Sinne der Mathematik. Was sie zurückgibt, hängt nicht nur von der Eingabe, sondern auch von z ab.
Dies ist etwas, das Sie bereits sehr gut kennen, eine Methode von Objekten stützt sich fast immer auf den Zustand von Objekten. Deshalb sagen manche Leute: "Schließungen sind die Objekte des armen Mannes. "Aber wir könnten Objekte auch als die Closures des armen Mannes betrachten, da wir Funktionen erster Klasse wirklich mögen.
Ich verwende Schema zur Veranschaulichung der Ideen, da Schema eine der frühesten Sprachen ist, die echte Abschlüsse hat. Das gesamte Material hier wird viel besser in SICP Kapitel 3 dargestellt.
Zusammenfassend lässt sich sagen, dass Lambda und Closure wirklich unterschiedliche Konzepte sind. Ein lambda ist eine Funktion. Eine Closure ist ein Paar aus Lambda und der entsprechenden Umgebung, die das Lambda abschließt.
Das Konzept ist dasselbe wie oben beschrieben, aber wenn Sie PHP-Kenntnisse haben, wird dies anhand von PHP-Code weiter erläutert.
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, function ($v) { return $v > 2; });
function ($v) { return $v > 2; } ist die Definition der Lambda-Funktion. Wir können sie sogar in einer Variablen speichern, damit sie wiederverwendet werden kann:
$max = function ($v) { return $v > 2; };
$input = array(1, 2, 3, 4, 5);
$output = array_filter($input, $max);
Was aber, wenn Sie die maximal zulässige Anzahl im gefilterten Array ändern wollen? Dann müssten Sie eine weitere Lambda-Funktion schreiben oder eine Closure erstellen (PHP 5.3):
$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 Closure ist eine Funktion, die in ihrer eigenen Umgebung ausgewertet wird und eine oder mehrere gebundene Variablen hat, auf die beim Aufruf der Funktion zugegriffen werden kann. Sie stammen aus der Welt der funktionalen Programmierung, wo eine Reihe von Konzepten im Spiel sind. Closures sind wie Lambda-Funktionen, aber intelligenter in dem Sinne, dass sie die Möglichkeit haben, mit Variablen aus der Umgebung, in der die Closure definiert ist, zu interagieren.
Hier ist ein einfacheres Beispiel für eine PHP-Schließung:
$string = "Hello World!";
$closure = function() use ($string) { echo $string; };
$closure();
Diese Frage ist alt und wurde schon oft beantwortet.
Jetzt mit Java 8 und Official Lambda, die inoffizielle Abschlussprojekte sind, stellt sich die Frage erneut.
Die Antwort im Java-Kontext (über Lambdas und Schließungen - was ist der Unterschied? ):
"Ein Closure ist ein Lambda-Ausdruck, der mit einer Umgebung gepaart ist, die jede seiner freien Variablen an einen Wert bindet. In Java werden Lambda-Ausdrücke mit Hilfe von Closures implementiert, daher werden die beiden Begriffe in der Community synonym verwendet."
Lambda vs. Schließung
Lambda
es anonyme Funktion(Methode)
Closure
ist eine Funktion, die schließt sich um (Einfangen) von Variablen aus dem umschließenden Bereich (z. B. nicht-lokale Variablen)
Java
interface Runnable {
void run();
}
class MyClass {
void foo(Runnable r) {
}
//Lambda
void lambdaExample() {
foo(() -> {});
}
//Closure
String s = "hello";
void closureExample() {
foo(() -> { s = "world";});
}
}
Schnell [Schließung]
class MyClass {
func foo(r:() -> Void) {}
func lambdaExample() {
foo(r: {})
}
var s = "hello"
func closureExample() {
foo(r: {s = "world"})
}
}
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.