提问人:Rupam Bhattacharjee 提问时间:3/13/2020 最后编辑:Mario GalicRupam Bhattacharjee 更新时间:3/13/2020 访问量:307
Scala 中的惰性计算、thunk 和函数闭包
Lazy evaluation, thunk and function closure in Scala
问:
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
使用非严格参数并返回 的实例。
创建时,它将获得 .因此,当 hello 被打印两次并通过应用 elem 创建时,这是有道理的。Test[Int]
a1
elem = () => { println("hello"); 1 }
a2
a3
test2
还使用非严格参数并返回 的实例。
创建时,它将获得 .未计算,绑定到调用方 - 。当应用于创建时,通过 ,得到计算(从而打印 hello)
然后缓存结果,即 .对 while creating 的后续调用使用计算值。然而,由于它不是本地的,所以这一切的唯一方法就是通过闭包。Test[Int]
b1
elem = () => y
y
test2
elem
b2
elem()
y
1
elem()
b3
y
elem
这准确吗?
注意:我已经浏览了这里发布的示例:Scala 惰性评估和应用函数,但这并不是我想要理解的
答:
2赞
som-snytt
3/13/2020
#1
您可以使用 查看捕获元素的实现。scalac -Vprint:_
在本例中,
def test2(v: Function0): Test = {
lazy <artifact> val y$lzy: scala.runtime.LazyInt = new scala.runtime.LazyInt();
new Test({
(() => Fun.this.$anonfun$test2$1(y$lzy, v))
})
};
惰性局部变为堆分配,并将引用传递到闭包中。
评论