La diferencia entre ellos es que un val
se ejecuta cuando se define, mientras que un lazy val
se ejecuta cuando se accede por primera vez.
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
En contraste con un método (que se define con def
) un lazy val
se ejecuta una vez y luego nunca más. Esto puede ser útil cuando una operación tarda mucho tiempo en completarse y cuando no se sabe con seguridad si se usará más tarde.
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
Aquí, cuando no se utilizan los valores x
y y
, sólo x
el desperdicio de recursos innecesariamente. Si suponemos que y
no tiene efectos secundarios y que no sabemos con qué frecuencia se accede (nunca, una vez, miles de veces) es inútil declararlo como def
ya que no queremos ejecutarlo varias veces.
Si desea saber cómo se implementan lazy vals
, consulte este question.
Como complemento: @ViktorKlang publicado en Twitter: ["Poco conocido hecho de Scala: si la inicialización de un val perezoso arroja un exce ption, intentará reinicializar el val en el siguiente acceso. "] (https://twitter.com/#!/viktorklang/status/104483846002704384) –