在scala中做一个懒惰的变量 [英] make a lazy var in scala

查看:51
本文介绍了在scala中做一个懒惰的变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Scala不允许创建laze var,只能创建lazy val.有道理.

Scala does not permit to create laze vars, only lazy vals. It make sense.

但是我碰到了用例,我想拥有类似的功能.我需要一个懒惰的变量持有人.可以为其分配一个值,该值应通过耗时的算法来计算.但是稍后可能会将其重新分配给另一个值,我根本不想调用第一个值计算.

But I've bumped on use case, where I'd like to have similar capability. I need a lazy variable holder. It may be assigned a value that should be calculated by time-consuming algorithm. But it may be later reassigned to another value and I'd like not to call first value calculation at all.

假设存在一些不可思议的var定义的示例

Example assuming there is some magic var definition

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

This piece of code should only call calc2(), not calc1

我有一个想法,该如何使用隐式转换和特殊的容器类编写此容器.我很想知道是否有任何不需要我编写不必要代码的嵌入式scala功能

I have an idea how I can write this container with implicit conversions and and special container class. I'm curios if is there any embedded scala feature that doesn't require me write unnecessary code

推荐答案

这有效:

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()

具有隐式隐含性让我有点担心,因为它适用范围广,可能会导致应用程序意外或有关隐式隐含性的编译器错误.

Having the implicit worries me slightly because it is widely applicable, which might lead to unexpected applications or compiler errors about ambiguous implicits.



另一种解决方案是使用带有setter和getter方法的包装对象,这些对象为您实现了惰性行为:



Another solution is using a wrapper object with a setter and a getter method that implement the lazy behaviour for you:

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中做一个懒惰的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆