case class Test[A](elem: () => A)
object Fun extends App {
def test1(v: => Int): Test[Int] = Test(() => v)
val a1 = test1({ println("hello"); 1 })
val a2 = a1.elem() //echoes hello
val a3 = a1.elem() //echoes hello
def test2(v: => Int): Test[Int] = {
lazy val y = v
Test(() => y)
}
val b1 = test2({ println("hello"); 1 })
val b2 = b1.elem() //echoes hello
val b3 = b1.elem() //doesn't echo hello. Is function closure at work here?
}
Test - это класс case, который принимает объект типа Function0[A]
в качестве аргумента конструктора.
test1
использует не строгий параметр и возвращает экземпляр Test[Int]
. когда a1
создан, он получает elem = () => { println("hello"); 1 }
. И поэтому имеет смысл, когда hello печатается дважды, в то время как a2
и a3
создаются путем применения elem.
test2
также использует не строгий параметр и возвращает экземпляр Test[Int]
. когда b1
создан, он получает elem = () => y
. y
не оценен и привязан к вызывающей стороне - test2
. Когда elem
применяется для создания b2
, через elem()
, y
оценивается (и, таким образом, печатается hello ), а затем кэширует результат, равный 1
. Последующий вызов elem()
при создании b3
использует оцененное значение. Однако, поскольку y
не является локальным по отношению к elem
, единственный способ, с помощью которого все это может работать, - это закрытие.
Это точно?
Примечание: я просмотрел приведенный здесь пример : Scala ленивая оценка и применение функции но это не совсем то, что я пытаюсь понять