Я хотел бы объяснить различия с помощью примера, который я выполнил в REPL. Я считаю, что этот простой пример легче понять и объяснить концептуальные различия.
Здесь я создаю val result1, alazy val result2 и def result3, каждый из которых имеет тип String.
A).val
scala> val result1 = {println("hello val"); "returns val"}
hello val
result1: String = returns val
Здесь println выполняется, потому что здесь вычислено значение result1.Итак, теперь result1 всегда будет ссылаться на свое значение, то есть «возвращает val».
scala> result1
res0: String = returns val
Итак, теперь вы можете видеть, что result1 теперь ссылается на свое значение.Обратите внимание, что оператор println здесь не выполняется, потому что значение для result1 уже было вычислено, когда оно было выполнено в первый раз.Итак, теперь, result1 всегда будет возвращать одно и то же значение, и оператор println больше никогда не будет выполняться, потому что вычисление для получения значения result1 уже выполнено.
B).lazy val
scala> lazy val result2 = {println("hello lazy val"); "returns lazy val"}
result2: String = <lazy>
Как мы видим здесь, оператор println здесь не выполняется, и ни одно значение не было вычислено.Такова природа ленивости.
Теперь, когда я впервые обращаюсь к result2, оператор println будет выполнен, а значение будет вычислено и присвоено.
scala> result2
hello lazy val
res1: String = returns lazy val
Теперь,когда я снова обращаюсь к result2, на этот раз мы увидим только значение, которое оно содержит, и оператор println не будет выполнен.Отныне result2 будет просто вести себя как val и все время возвращать свое кэшированное значение.
scala> result2
res2: String = returns lazy val
C).def
В случае def результат должен вычисляться при каждом вызове result3.Это также основная причина того, что мы определяем методы как def в scala, потому что методы должны вычислять и возвращать значение каждый раз, когда оно вызывается внутри программы.
scala> def result3 = {println("hello def"); "returns def"}
result3: String
scala> result3
hello def
res3: String = returns def
scala> result3
hello def
res4: String = returns def