Les différences entre ces trois façons de définir une fonction en Scala
Donné trois façons 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
Comment ces définitions diffèrent-ils? Le REPL n'indique pas de différences évidentes:
scala> f1
res38: (Int) => Int = <function1>
scala> f2
res39: (Int) => Int = <function1>
scala> f3
res40: (Int) => Int = <function1>
- Vous devriez noter que dans le 2e bloc ci-dessus, l'évaluation de
f1
dans le REPL montre la valeur statiquement lié àf1
tout en évaluantf2
etf3
montrent le résultat de l'invocation de ces méthodes. En particulier, une nouvelleFunction1[Int, Int]
instance est produit chaque fois que l'f2
ouf3
est invoquée, alors quef1
est la mêmeFunction1[Int, Int]
pour toujours. - étant donné que le val de version n'a pas besoin d'une nouvelle fonction de l'instance, pourquoi aurait-on jamais utiliser def dans ce cas?
- La seule situation que je peux me rappeler où l'on voit des defs rendement Fonctionn[...] des valeurs est dans le combinator parser. Ce n'est pas très commun de méthodes d'écriture que le rendement des fonctions et pratiquement jamais ne serait-on utiliser un def de rendement nombre de copies d'un point de vue sémantique / fonctionnellement immuable de la fonction.
Vous devez vous connecter pour publier un commentaire.
f1
est une fonction qui prend un entier et retourne un entier.f2
est une méthode avec zéro arité qui retourne une fonction qui prend un entier et retourne un entier. (Lorsque vous tapezf2
à REPL plus tard, il devient un appel à la méthodef2
.)f3
est la même quef2
. Vous n'êtes pas employer l'inférence de type il.f1
est unfunction
etf2
est unmethod
?apply
. Une méthode est une méthode.À l'intérieur d'une classe,
val
est évaluée lors de l'initialisation, tandis quedef
est évaluée uniquement lorsque, et à chaque fois, la fonction est appelée. Dans le code ci-dessous, vous verrez que x est évaluée la première fois que l'objet est utilisé, mais pas encore quand le x membre est accessible. En revanche, y est pas évalué lorsque l'objet est instancié, mais est évalué à chaque fois que le membre est accessible.a
est immuable et évaluées lors de l'initialisation, maisb
reste une valeur mutable. Donc, la référence àb
est définie lors de l'initialisation, mais la valeur stockée parb
reste mutable. Pour le plaisir, vous pouvez maintenant créer un nouveauval b = 123
. Après cela, votrea(5)
donnera toujours 11, depuis leb
est maintenant complètement une nouvelle valeur.De l'exécution d'une définition comme def x = e ne sera pas évaluer l'expression e. Au lieu de cela e est évalué chaque fois que x est utilisé. Sinon, Scala propose une définition de la valeur
val x = e, qui n'est d'évaluer la droite 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 le
pré-calculé la valeur de e, de sorte que l'expression n'a pas besoin d'être évalué de nouveau.