Quelle est la différence entre :
et
Les deux peuvent être appelées comme `` .
Quelle est la différence entre :
et
Les deux peuvent être appelées comme `` .
Méthode def even
évalue sur appel et crée de nouvelles fonction de tous les temps, la nouvelle instance de l' Function1
).
def even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = false
val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
Avec def
vous pouvez obtenir nouvelle fonction à chaque appel:
val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1049057402
test()
// Int = -1049057402 - same result
def test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -240885810
test()
// Int = -1002157461 - new result
val
évalue lorsqu'il est défini, def
- lorsqu'il est appelé à:
scala> val even: Int => Boolean = ???
scala.NotImplementedError: an implementation is missing
scala> def even: Int => Boolean = ???
even: Int => Boolean
scala> even
scala.NotImplementedError: an implementation is missing
Notez qu'il y a une troisième option: lazy val
.
Il évalue lorsqu'il est appelé première fois:
scala> lazy val even: Int => Boolean = ???
even: Int => Boolean = <lazy>
scala> even
scala.NotImplementedError: an implementation is missing
Mais retourne le même résultat (dans ce cas, même instance d' FunctionN
) à chaque fois:
lazy val even: Int => Boolean = _ % 2 == 0
even eq even
//Boolean = true
lazy val test: () => Int = {
val r = util.Random.nextInt
() => r
}
test()
// Int = -1068569869
test()
// Int = -1068569869 - same result
Performance
val
évalue quand définis.
def
évalue à chaque appel, de sorte que la performance pourrait être pire, alors avec val
pour les appels multiples. Vous pourrez obtenir les mêmes performances avec un seul appel. Et avec pas d'appels, vous aurez pas de frais généraux à partir d' def
, de sorte que vous pouvez le définir, même si vous ne l'utilisez pas dans certaines branches.
Avec un lazy val
vous obtiendrez une évaluation différée: vous pouvez la définir, même si vous n'allez pas l'utiliser dans certaines branches, et qu'il évalue une fois ou jamais, mais vous aurez un peu de surcharge de double-vérifier le verrouillage de tous les accès à votre lazy val
.
@SargeBorsch noté, vous pouvez définir une méthode, et c'est l'option la plus rapide:
def even(i: Int): Boolean = i % 2 == 0
Mais si vous avez besoin d'une fonction (pas de méthode) pour la fonction de composition ou pour des fonctions d'ordre supérieur (comme filter(even)
) compilateur va générer une fonction de votre méthode à chaque fois que vous l'utilisez en tant que fonction, de sorte que les performances pourraient légèrement pire que val
.
Réfléchissez à ceci:
scala> def even: (Int => Boolean) = {
println("def");
(x => x % 2 == 0)
}
even: Int => Boolean
scala> val even2: (Int => Boolean) = {
println("val");
(x => x % 2 == 0)
}
val //gets printed while declaration. line-4
even2: Int => Boolean = <function1>
scala> even(1)
def
res9: Boolean = false
scala> even2(1)
res10: Boolean = false
Voyez-vous la différence? En bref:
def: Pour chaque appel à l' even
, il appelle le corps de l' even
méthode de nouveau. Mais avec even2
c'est à dire de val, la fonction est initialisé qu'une seule fois alors que la déclaration (et par conséquent, il imprime val
à la ligne 4 et de ne plus jamais) et la même sortie est utilisée chaque fois qu'il accède à l'. Par exemple, essayez de faire cela:
scala> import scala.util.Random
import scala.util.Random
scala> val x = { Random.nextInt }
x: Int = -1307706866
scala> x
res0: Int = -1307706866
scala> x
res1: Int = -1307706866
Lors de l' x
d'initialisation, la valeur retournée par Random.nextInt
est défini comme la valeur finale de l' x
. La prochaine fois, x
est utilisé à nouveau, il retournera toujours la même valeur.
Vous pouvez aussi paresseusement initialiser x
. c'est à dire la première fois qu'il est utilisé, il est initialisé et non lors de la déclaration. Par exemple:
scala> lazy val y = { Random.nextInt }
y: Int = <lazy>
scala> y
res4: Int = 323930673
scala> y
res5: Int = 323930673
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.