Bei drei Möglichkeiten, dieselbe Funktion auszudrücken f(a) := a + 1
:
val f1 = (a:Int) => a + 1
def f2 = (a:Int) => a + 1
def f3:(Int => Int) = a => a + 1
Wie unterscheiden sich diese Definitionen? Die REPL weist keine offensichtlichen Unterschiede auf:
scala> f1
res38: (Int) => Int = <function1>
scala> f2
res39: (Int) => Int = <function1>
scala> f3
res40: (Int) => Int = <function1>
f1
in der REPL den Wert anzeigt, an den sief1
während der Auswertung statisch gebunden ist,f2
undf3
das Ergebnis des Aufrufs dieser Methoden anzeigt . InsbesondereFunction1[Int, Int]
wird jedes Mal eine neue Instanz erstelltf2
oderf3
aufgerufen, während sie für immerf1
dieselbe istFunction1[Int, Int]
.Antworten:
f1
ist eine Funktion, die eine Ganzzahl akzeptiert und eine Ganzzahl zurückgibt.f2
ist eine Methode mit einer Arität von Null, die eine Funktion zurückgibt, die eine Ganzzahl und eine Ganzzahl zurückgibt. (Wenn Sief2
später bei REPL eingeben, wird die Methode aufgerufenf2
.)f3
ist das gleiche wief2
. Sie verwenden dort einfach keine Typinferenz.quelle
f1
ist einfunction
undf2
ist einmethod
?apply
. Eine Methode ist eine Methode.f2
selbst akzeptiert keine Argumente. Das zurückgegebene Funktionsobjekt funktioniert.Innerhalb einer Klasse
val
wird bei der Initialisierungdef
ausgewertet, während sie nur ausgewertet wird, wenn und jedes Mal die Funktion aufgerufen wird. Im folgenden Code sehen Sie, dass x bei der ersten Verwendung des Objekts ausgewertet wird, jedoch nicht erneut, wenn auf das x-Element zugegriffen wird. Im Gegensatz dazu wird y nicht ausgewertet, wenn das Objekt instanziiert wird, sondern jedes Mal, wenn auf das Mitglied zugegriffen wird.quelle
a
ist unveränderlich und wird bei der Initialisierung ausgewertet,b
bleibt jedoch ein veränderbarer Wert. Der Verweis aufb
wird also während der Initialisierung gesetzt, aber der von gespeicherte Wertb
bleibt veränderbar. Zum Spaß können Sie jetzt eine neue erstellenval b = 123
. Danach geben Siea(5)
immer 11, da diesb
nun ein völlig neuer Wert ist.Durch Ausführen einer Definition wie def x = e wird der Ausdruck e nicht ausgewertet . Stattdessen wird e immer dann ausgewertet, wenn x verwendet wird. Alternativ bietet Scala eine Wertedefinition val x = e an , die das rechte e als Teil der Bewertung der Definition bewertet. Wenn x anschließend verwendet wird, wird es sofort durch den vorberechneten Wert von e ersetzt , sodass der Ausdruck nicht erneut ausgewertet werden muss.
quelle