Étant donné trois manières d'exprimer la même fonction f(a) := a + 1
:
val f1 = (a:Int) => a + 1
def f2 = (a:Int) => a + 1
def f3:(Int => Int) = a => a + 1
En quoi ces définitions diffèrent-elles? Le REPL n'indique aucune différence évidente:
scala> f1
res38: (Int) => Int = <function1>
scala> f2
res39: (Int) => Int = <function1>
scala> f3
res40: (Int) => Int = <function1>
f1
dans la REPL montre la valeur liée statiquementf1
lors de l'évaluationf2
etf3
affiche le résultat de l' appel de ces méthodes. En particulier, une nouvelleFunction1[Int, Int]
instance est produite à chaque fois quef2
ouf3
est invoquée, alors qu'ellef1
est la mêmeFunction1[Int, Int]
pour toujours.Réponses:
f1
est une fonction qui prend un entier et renvoie un entier.f2
est une méthode avec une arité nulle qui renvoie une fonction qui prend un entier et renvoie un entier. (Lorsque vous tapezf2
à REPL plus tard, cela devient un appel à la méthodef2
.)f3
est le même quef2
. Vous n'employez tout simplement pas l'inférence de type ici.la source
f1
afunction
etf2
est-ce unmethod
?apply
. Une méthode, eh bien, est une méthode.f2
lui - même n'accepte aucun argument. L'objet fonction qu'il renvoie le fait.À l'intérieur d'une classe,
val
est évalué à l'initialisation tandis quedef
n'est évalué que lorsque, et à chaque fois , la fonction est appelée. Dans le code ci-dessous, vous verrez que x est évalué la première fois que l'objet est utilisé, mais pas à nouveau lors de l'accès au membre x. En revanche, y n'est pas évalué lorsque l'objet est instancié, mais est évalué à chaque fois que le membre est accédé.la source
a
est immuable et évaluée à l'initialisation, maisb
reste une valeur modifiable. La référence àb
est donc définie lors de l'initialisation, mais la valeur stockée parb
reste mutable. Pour le plaisir, vous pouvez maintenant créer un nouveau fichierval b = 123
. Après cela, vousa(5)
donnerez toujours 11, car la valeurb
est maintenant complètement nouvelle.L'exécution d'une définition telle que def x = e n'évaluera pas l'expression e . Au lieu de cela, e est évalué chaque fois que x est utilisé. Alternativement, Scala propose une définition de valeur val x = e , qui évalue le côté droit e dans le cadre de l'évaluation de la définition. Si x est ensuite utilisé par la suite, il est immédiatement remplacé par la valeur pré-calculée de e , de sorte que l'expression n'a pas besoin d'être évaluée à nouveau.
la source