// closures1.scalaWir definieren eine Funktion
def zaehlerMitStartwert(startwert: Int): (() => Int) = {
var n = startwert
def nplus1(): Int = { n=n+1; n }
nplus1
}
val next1 = zaehlerMitStartwert(10)
val next2 = zaehlerMitStartwert(20)
println( next1() )
println( next2() )
println( next2() )
println( next1() )
zaehlerMitStartwert()
, die den Startwert als Int-Parameter übergeben bekommt. Rückgabe dieser Funktion ist eine Funktion, die keine Parameter hat, aber einen Int-Wert zurückgibt.Innerhalb der äußeren Funktion legen wir eine Zählvariable
n
an, da der Übergabeparameter startwert
unveränderlich ist. Dann definieren wir eine verschachtelte Funktion nplus1()
, die auf die Zählvariable n
eins draufzählt und als letzten Ausdruck der Funktion das hochgezählte n
zurückgibt. Hier findet der Funktionsabschluss statt - das Binden der Variablen n
, die als lokale Variable in der umgebenden Funktion definiert ist. Als letzten Ausdruck in der äußeren Funktion geben wir die Funktion nplus1
als Ergebnis zurück.Das ganze geht auch etwas kürzer und "funktionaler", wenn man die innere Funktion nicht explizit definiert, sondern als letzten Ausdruck der äußeren Funktion gleich ein entsprechendes Funktionsliteral hinschreibt:
// closures2.scalaBeide Skripte liefern dieselbe Ausgabe:
def zaehlerMitStartwert(startwert: Int) = {
var n = startwert
() => { n=n+1; n }
}
val next1 = zaehlerMitStartwert(10)
val next2 = zaehlerMitStartwert(20)
println( next1() )
println( next2() )
println( next2() )
println( next1() )
HeartOfGold:~ much$ scala closures2.scalaWenn man den Scala-Interpreter mit
11
21
22
12
scala -savecompiled closures2.scala
aufruft, erhält man ein JAR-Archiv, in dem man sich die generierten Java-Bytecode-Dateien anschauen kann. In diesem Fall werden vier class
-Dateien erzeugt.