Scala 惰性 val 缓存
Scala lazy val caching
在下面的例子中:
def maybeTwice2(b: Boolean, i: => Int) = {
lazy val j = i
if (b) j+j else 0
}
为什么我这样调用时hi没有打印两次:
maybeTwice2(true, { println("hi"); 1+41 })
这个例子实际上来自 "Functional Programming in Scala" 一书,"hi" 没有被打印两次的原因对我来说没有足够的说服力。所以才想到在这里问这个问题!
所以i
是一个给出整数的函数吧?当您调用该方法时,您将 b
传递为 true 并执行 if 语句的第一个分支。
发生的事情是 j
被设置为 i
并且它在以后第一次用于计算时会执行函数,打印 "hi" 并缓存结果值 1 + 41 = 42
。第二次使用时,结果值已经计算出来,因此函数 returns 84,不需要计算函数两次,因为 lazy val j
.
本文 SO answer 探讨了惰性 val 是如何在内部实现的。在j + j
中,j
是一个lazy val,相当于一个函数,它执行您为定义lazy val而提供的代码,returns一个整数并将其缓存以供进一步调用。所以它打印 hi
和 returns 1+41 = 42
。然后第二个 j
被评估,并调用相同的函数。除了这次,它不是 运行 您的代码,而是从缓存中获取值 (42)。然后将两个整数相加(返回 84)。
在下面的例子中:
def maybeTwice2(b: Boolean, i: => Int) = {
lazy val j = i
if (b) j+j else 0
}
为什么我这样调用时hi没有打印两次:
maybeTwice2(true, { println("hi"); 1+41 })
这个例子实际上来自 "Functional Programming in Scala" 一书,"hi" 没有被打印两次的原因对我来说没有足够的说服力。所以才想到在这里问这个问题!
所以i
是一个给出整数的函数吧?当您调用该方法时,您将 b
传递为 true 并执行 if 语句的第一个分支。
发生的事情是 j
被设置为 i
并且它在以后第一次用于计算时会执行函数,打印 "hi" 并缓存结果值 1 + 41 = 42
。第二次使用时,结果值已经计算出来,因此函数 returns 84,不需要计算函数两次,因为 lazy val j
.
本文 SO answer 探讨了惰性 val 是如何在内部实现的。在j + j
中,j
是一个lazy val,相当于一个函数,它执行您为定义lazy val而提供的代码,returns一个整数并将其缓存以供进一步调用。所以它打印 hi
和 returns 1+41 = 42
。然后第二个 j
被评估,并调用相同的函数。除了这次,它不是 运行 您的代码,而是从缓存中获取值 (42)。然后将两个整数相加(返回 84)。