scala - Scala 中的惰性求值、thunk 和函数闭包
问题描述
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 是一个将类型对象Function0[A]
作为构造函数参数的案例类。
test1
使用非严格参数并返回Test[Int]
. 创建时a1
,它得到elem = () => { println("hello"); 1 }
. 因此,当hello被打印两次a2
并a3
通过应用 elem 创建时,这是有意义的。
test2
还使用非严格参数并返回Test[Int]
. 创建时b1
,它得到elem = () => y
. 未y
评估并绑定到调用者 - test2
。Whenelem
应用于 create b2
, through elem()
,y
被评估(并因此打印hello),然后缓存结果为1
. elem()
创建时的后续调用b3
使用评估值。但是,由于y
不是本地的elem
,所有这些都可以工作的唯一方法是通过关闭。
那准确吗?
注意:我已经浏览了此处发布的示例:Scalalazy evaluation and apply function,但这并不是我想要理解的
解决方案
您可以使用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))
})
};
惰性局部变为堆分配的,引用传递到闭包中。
推荐阅读
- ckeditor - 导入带格式的 RTF 文本
- javascript - 如何在 JS 中删除正确的对象属性值
- angular - 无法以编程方式禁用角度材料日期选择器
- r - 如何将数字格式化为百分比并限制小数位数
- css - 如何修复仅在 IOS 上出现的网站意外水平倾斜?
- planning - 在 PDDL 2.1 中分配除法值,公制 FF
- python - 谷歌浏览器如何处理 html 页面?
- asp.net-mvc - 托管 ASP.NET MVC 应用程序时,Serilog 不登录数据库
- r - 在 R 中使用 ggplot2 为具有不同渐变的单行着色
- c# - 有没有办法让数组保存 blazor 组件?