【问题标题】:Scala lazy val cachingScala 惰性 val 缓存
【发布时间】:2015-01-13 11:08:06
【问题描述】:

在以下示例中:

def maybeTwice2(b: Boolean, i: => Int) = {
  lazy val j = i
  if (b) j+j else 0
}

为什么当我这样称呼它时 hi 没有打印两次:

maybeTwice2(true, { println("hi"); 1+41 })

这个例子实际上来自“Scala 中的函数式编程”一书,给出的原因是为什么“hi”没有被打印两次,这对我来说不够有说服力。所以就想在这里问这个!

【问题讨论】:

  • 请接受答案或要求更详细的解释。
  • 目前尚不清楚为什么您认为“给出的理由”“没有说服力”。 i 是一个函数。 maybeTwice2 引用(调用)一次。为什么你期望它一开始会被调用两次?
  • 我本来希望你给出的解释会出现在书中。这对我来说更有意义!

标签: scala thunk


【解决方案1】:

所以i 是一个给出整数的函数,对吧?当您调用该方法时,您将 b 作为 true 并执行 if 语句的第一个分支。

发生的情况是j 被设置为i,并且稍后在计算中第一次使用它时,它会执行函数,打印“hi”并缓存结果值1 + 41 = 42。第二次使用时,结果值已经计算出来,因此函数返回 84,因为lazy val j 而不需要计算两次函数。

【讨论】:

    【解决方案2】:

    SO answer 探讨了惰性 val 是如何在内部实现的。在j + j 中,j 是一个惰性 val,相当于一个函数,它执行您为定义惰性 val 提供的代码,返回一个整数并缓存它以供进一步调用。所以它打印hi 并返回1+41 = 42。然后第二个j 被评估,并调用相同的函数。除了这一次,它不是运行您的代码,而是从缓存中获取值 (42)。然后将两个整数相加(返回 84)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-22
      • 2014-10-07
      • 2012-04-27
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多