5.9. Wartości leniwe
W przypadku definiowania wartości za pomocą val, można tę wartość uczynić leniwą poprzedzając definicję modyfikatorem lazy. Tak zdefiniowana wartość zostanie zainicjowana podczas pierwszego odwołania do niej, a nie już w momencie jej definiowania.
Plik Lazy1.scala: class Lazy1 { println("constructor - start") lazy val a = { println("initializing a"); 1 } println("constructor - stop") }
W klasie Lazy1, zdefiniowanej w pliku Lazy1.scala, wartość a nie zostaje zainicjalizowana podczas tworzenia instancji klasy, ale dopiero później, przy pierwszym odwołaniu do niej.
scala> val x1 = new Lazy1 constructor - start constructor - stop x1: Lazy1 = Lazy1@18a9499 scala> x1.a initializing a res0: Int = 1 scala> x1.a res1: Int = 1
Użycie wartości leniwej nie wyklucza zainicjalizowania jej w czasie konstruowania obiektu.
Plik Lazy2.scala: class Lazy2 { println("constructor - start") val b = a println("in constructor") lazy val a = { println("initializing a"); 1 } println("constructor - stop") }
W klasie Lazy2, zdefiniowanej w pliku Lazy2.scala, odwołanie do wartości a następuje już podczas tworzenia obiektu, a do tego przed definicją samej wartości.
scala> val x2 = new Lazy2 constructor - start initializing a in constructor constructor - stop x2: Lazy2 = Lazy2@c0a64d
Przykład z pliku Lazy3.scala ilustruje jeszcze inną możliwość, a mianowicie odwoływanie się do wartości leniwej przez wyrażenie inicjalizujące inną taką wartość.
Plik Lazy3.scala: class Lazy3 { println("constructor - start") lazy val b = { println("initializing b"); a } println("in constructor") lazy val a = { println("initializing a"); 1 } println("constructor - stop") }
Kolejność wywoływania wyrażeń inicjalizujących zależy w tym przypadku od kolejności użycia odpowiednich wartości.
scala> val x3 = new Lazy3 constructor - start in constructor constructor - stop x3: Lazy3 = Lazy3@b61c56
scala> x3.b initializing b initializing a res2: Int = 1 scala> x3.a res3: Int = 1 scala> val y3 = new Lazy3 constructor - start in constructor constructor - stop y3: Lazy3 = Lazy3@1eedb64 scala> y3.a initializing a res4: Int = 1 scala> y3.b initializing b res5: Int = 1