La differenza tra loro è che un val
viene eseguito quando viene definito mentre un lazy val
viene eseguito quando viene effettuato l'accesso la prima volta.
scala> val x = { println("x"); 15 }
x
x: Int = 15
scala> lazy val y = { println("y"); 13 }
y: Int = <lazy>
scala> x
res2: Int = 15
scala> y
y
res3: Int = 13
scala> y
res4: Int = 13
Contrariamente a un metodo (definito con def
) un lazy val
viene eseguita una volta e poi mai più. Ciò può essere utile quando un'operazione richiede molto tempo per essere completata e quando non è sicuro se verrà utilizzata in un secondo momento.
scala> class X { val x = { Thread.sleep(2000); 15 } }
defined class X
scala> class Y { lazy val y = { Thread.sleep(2000); 13 } }
defined class Y
scala> new X
res5: X = [email protected] // we have to wait two seconds to the result
scala> new Y
res6: Y = [email protected] // this appears immediately
Qui, quando i valori x
e y
non sono mai utilizzati, solo x
risorse inutilmente spreco. Se supponiamo che non abbia effetti collaterali e che non sappiamo con quale frequenza si acceda (mai, una volta, migliaia di volte) è inutile dichiararlo come def
poiché non vogliamo eseguirlo più volte.
Se si desidera sapere come sono implementate le misure lazy vals
, vedere questo question.
Come supplemento: @ViktorKlang postato su Twitter: ["Scala Scala poco nota: se l'inizializzazione di un valore lazy lancia un exce ption, tenterà di reinizializzare la val al prossimo accesso. "] (https://twitter.com/#!/viktorklang/status/104483846002704384) –