Ai-je raison de comprendre que
def
est évalué à chaque accèslazy val
est évalué dès qu'il est accédéval
est évalué une fois qu'il est entré dans la portée de l'exécution?
Ai-je raison de comprendre que
def
est évalué à chaque accès
lazy val
est évalué dès qu'il est accédé
val
est évalué une fois qu'il est entré dans la portée de l'exécution?
Oui, mais il y a un bon truc: si vous avez une valeur paresseuse, et lors de la première évaluation, elle obtiendra une exception, la prochaine fois que vous essaierez d'y accéder, elle tentera de se réévaluer elle-même.
Voici un exemple:
scala> import io.Source
import io.Source
scala> class Test {
| lazy val foo = Source.fromFile("./bar.txt").getLines
| }
defined class Test
scala> val baz = new Test
baz: Test = Test@ea5d87
//right now there is no bar.txt
scala> baz.foo
java.io.FileNotFoundException: ./bar.txt (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:137)
...
// now I've created empty file named bar.txt
// class instance is the same
scala> baz.foo
res2: Iterator[String] = empty iterator
Oui, bien que pour le troisième, je dirais "lorsque cette instruction est exécutée", car, par exemple:
def foo() {
new {
val a: Any = sys.error("b is " + b)
val b: Any = sys.error("a is " + a)
}
}
Cela donne "b is null"
. b
n'est jamais évalué et son erreur n'est jamais renvoyée. Mais il entre dans le champ dès que le contrôle entre dans le bloc.
Une bonne raison pour choisir l' def
sur val
, surtout dans les classes abstraites (ou des caractères qui sont utilisés pour imiter Java les interfaces), est, que vous pouvez remplacer un def
avec un val
dans les sous-classes, mais pas l'inverse.
Concernant l' lazy
, il y a deux choses que je peux voir que l'on devrait avoir à l'esprit. La première est qu' lazy
introduit une certaine gestion d'exécution, mais je suppose que vous devez évaluer votre situation spécifique afin de déterminer si cette réalité a un impact significatif sur les performances d'exécution. L'autre problème avec l' lazy
est qu'il peut-être des retards de lever une exception, ce qui pourrait rendre plus difficile de raisonner à propos de votre programme, car l'exception est levée pas direct, mais seulement lors de la première utilisation.
Vous êtes correct. Pour preuve de la spécification:
De "3.3.1 Types de Méthode" (pour def
):
Sans paramètre méthodes nom des expressions qui sont réévalués à chaque fois la méthode sans paramètre nom est référencé.
De "4.1 les Déclarations de Valeur et de Définitions":
Une définition de la valeur
val x : T = e
définitx
, comme le nom de la valeur qui résulte de l'évaluation de l'e
.Un paresseux définition de la valeur évalue son côté droit,
e
le premier fois que la valeur est accessible.
def
définit une méthode. Lorsque vous appelez la méthode, la méthode ofcourse s'exécute.
val
définit une valeur (une variable immuable). L'expression d'affectation est évaluée lorsque la valeur est initialisée.
lazy val
définit une valeur avec initialisation différée. Il sera initialisé lors de sa première utilisation, donc l'expression d'affectation sera évaluée ensuite.
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.