2009-08-16 12 views
9

Fand den folgenden Ausschnitt auf der Closure Seite auf wikipediaScala Verschlüsse auf wikipedia

//# Return a list of all books with at least 'threshold' copies sold. 
def bestSellingBooks(threshold: Int) = bookList.filter(book => book.sales >= threshold) 
//# or 
def bestSellingBooks(threshold: Int) = bookList.filter(_.sales >= threshold) 

mich korrigieren, wenn ich falsch bin, aber das ist kein Verschluss? Es ist eine Funktion literal, eine anonyme Funktion, eine Lambda-Funktion, aber keine Schließung?

+0

Warum ist der Schwellenwert ein geschlossener Begriff? Es ist eine lokale Variable, die von der Funktion erfasst wird, wenn sie an die Filtermethode übergeben wird, nein? – skaffman

+0

Sie haben Recht. Schwelle ist kein geschlossener Begriff, seine freie Variable und die Schließung ist ein offener Begriff. – Schildmeijer

Antwort

14

Nun ... Wenn Sie technisch sein wollen, ist dies ein Funktionsliteral, das zur Laufzeit in einen Abschluss übersetzt wird, der die offenen Terme schließt (bindet sie an ein val/var im Bereich des Funktionsliterals). Im Kontext dieser Funktion literal (_.sales >= threshold) ist threshold eine freie Variable, da das Funktionsliteral selbst keine Bedeutung gibt. Für sich ist _.sales >= threshold ein offener Begriff Zur Laufzeit ist es bei jedem Aufruf der Funktion an die lokale Variable der Funktion gebunden.

Nehmen Sie diese Funktion zum Beispiel Verschlüsse zu erzeugen:

def makeIncrementer(inc: Int): (Int => Int) = (x: Int) => x + inc 

Zur Laufzeit erzeugt der folgende Code 3 Verschlüsse. Es ist auch interessant zu bemerken, dass b und c nicht der gleiche Verschluss sind (b == c ergibt false).

val a = makeIncrementer(10) 
val b = makeIncrementer(20) 
val c = makeIncrementer(20) 

Ich denke immer noch, dass das Beispiel, das auf Wikipedia gegeben wird, ein gutes ist, obwohl es nicht die ganze Geschichte vollständig bedeckt. Es ist ziemlich schwierig, ein Beispiel für tatsächliche Schließungen nach der strengsten Definition zu geben, ohne tatsächlich einen Speicherauszug eines laufenden Programms zu haben. Das Gleiche gilt für die Klassen-Objekt-Beziehung. Normalerweise geben Sie ein Beispiel für ein Objekt, indem Sie eine class Foo { ... definieren und dann mit val f = new Foo instanziieren, indem Sie sagen, dass f das Objekt ist.

-- Flaviu Cipcigan

Hinweise:

  • Referenz: Programmierung in Scala, Martin Odersky, Lex Löffel, Bill Venners
  • -Code kompiliert mit Scala Version 2.7.5.final auf Java läuft 1.6.0_14 .
+0

große Antwort +1 –

1

Ich bin mir nicht ganz sicher, aber ich denke, Sie haben Recht. Braucht eine Schließung keinen Zustand (ich denke freie Variablen ...)?

Oder ist die BuchListe die freie Variable?

+0

"Das Inferenzsystem von Scala erkennt das zu filternde Argument automatisch als eine Funktion, die ein Buch nimmt und einen booleschen Wert zurückgibt und es in eine Schließung verwandelt". – Schildmeijer

0

Soweit ich verstehe, ist dies ein Verschluss, der einen formalen Parameter enthält, Schwelle und Kontextvariable, booklist, aus dem umgebenden Gültigkeitsbereich. Daher kann sich der Rückgabewert (List [Any]) der Funktion ändern, während die Filterprädikatfunktion angewendet wird. Es variiert basierend auf den Elementen der List (bookList) -Variable aus dem Kontext.