scala - 在 Scala 中创建一个懒惰的 var

标签 scala lazy-evaluation

Scala 不允许创建惰性变量,只能创建惰性变量。有道理。

但是我遇到了用例,我希望拥有类似的功能。我需要一个懒惰的变量持有者。它可能会被分配一个应该由耗时算法计算的值。但是以后可能会重新分配给另一个值,我根本不想调用第一个值计算。

假设有一些神奇的 var 定义的示例

lazy var value : Int = _
val calc1 : () => Int = ... // some calculation
val calc2 : () => Int = ... // other calculation
value = calc1
value = calc2
val result : Int = value + 1

这段代码应该只调用calc2(),而不是calc1

我知道如何使用隐式转换和特殊容器类来编写这个容器。我很好奇是否有任何不需要我编写不必要代码的嵌入式 scala 功能

最佳答案

这有效:

var value: () => Int = _
val calc1: () => Int = () => { println("calc1"); 47 }
val calc2: () => Int = () => { println("calc2"); 11 }
value = calc1
value = calc2
var result = value + 1 /* prints "calc2" */

implicit def invokeUnitToInt(f: () => Int): Int = f()

隐式隐式让我有点担心,因为它广泛适用,这可能会导致意外的应用程序或关于模糊隐式的编译器错误。

另一种解决方案是使用带有 setter 和 getter 方法的包装器对象来为您实现惰性行为:
lazy val calc3 = { println("calc3"); 3 }
lazy val calc4 = { println("calc4"); 4 }

class LazyVar[A] {
  private var f: () => A = _
  def value: A = f() /* getter */
  def value_=(f: => A) = this.f = () => f /* setter */
}

var lv = new LazyVar[Int]
lv.value = calc3
lv.value = calc4
var result = lv.value + 1 /* prints "calc4 */

关于scala - 在 Scala 中创建一个懒惰的 var,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11289243/

相关文章:

scala - | + |是一个半群,为什么它需要一个monoid隐式解析

haskell - 在 Haskell 中观察惰性

scala - 如何基于大文本提取字符n-gram

scala - Scala中a.ne(null)和!= null有什么区别?

scala - 如何从scala中的子类调用父类(super class)构造函数以及如何进行构造函数链接

sorting - 如何在 Spark DataFrame 上应用部分排序?

c++ - &= 和 |= 运算符是否用于 boolean 短路?

r - 理解 R 函数惰性求值

scala - 是否可以使用单个关键字使 Scala 对象中的所有值变得懒惰

Scala 模式匹配选项 None 有或没有绑定(bind)