lazy val all exist to produce a value in Scala. Jolly good, right :)
To start with, values defined in
val are evaluated as soon as the object is initialised and the value will be stored throughout the lifetime of the object. Also the value defined by
val is immutable, it can’t be changed throughout the lifecycle either.
def is used to define a method, just like the method in Java, it is evaluated every time it is called. As long as the type definition is satisfied, any value could be produced after its invocation.
lazy val gives a little bit more flexibility, which is its value is only evaluated when first accessed, then the result is kept since, but can never be reassigned.
When an object is created, all
val values are instantiated, which implies the resource is instantly allocated.
From the results in REPL, you can easily tell while
Y is processed straight away, it took 2 seconds before
X finishes instantiation. It is fine if this is indeed what you wanted.
But to speed up the application, it might worth considering only evaluate some values when they are needed, instead of in the beginning. Situation like this, it is ideal to use
lazy val, which would save a lot of application initialisation time.
So far, it may sound like
lazy val is just an immutable version of
def. Well, that’s not the whole picture.
There are two things you probably have noticed by running the two blocks of code:
- the print line in
lazy valis only printed once, while the one in
defis printed a thousand times
- value defined with
lazy valexecutes more than twice as fast as the one defined with
The two observations are intriguingly linked because of the nature of
lazy val, which is a reference to start with, then turns into an immutable value and stays available throughout the process.
Therefore, it is worth adopting
def, if the value to access will never change and is likely to be accessed more than once.