- 2.1 Conditional Expressions
- 2.2 Statement Termination
- 2.3 Block Expressions and Assignments
- 2.4 Input and Output
- 2.5 Loops
- 2.6 Advanced for Loops and for Comprehensions
- 2.7 Functions
- 2.8 Default and Named Arguments L1
- 2.9 Variable Arguments L1
- 2.10 Procedures
- 2.11 Lazy Values L1
- 2.12 Exceptions
- Exercises
2.11 Lazy Values L1
When a val is declared as lazy, its initialization is deferred until it is accessed for the first time. For example,
lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
(We will discuss file operations in Chapter 9. For now, just take it for granted that this call reads all characters from a file into a string.)
If the program never accesses words, the file is never opened. To verify this, try it out in the REPL, but misspell the file name. There will be no error when the initialization statement is executed. However, when you access words, you will get an error message that the file is not found.
Lazy values are useful to delay costly initialization statements. They can also deal with other initialization issues, such as circular dependencies. Moreover, they are essential for developing lazy data structures—see Section 13.13, “Streams,” on page 173.
You can think of lazy values as halfway between val and def. Compare
val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString // Evaluated as soon as words is defined lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString // Evaluated the first time words is used def words = scala.io.Source.fromFile("/usr/share/dict/words").mkString // Evaluated every time words is used