是否可以使用单个关键字使scala对象中的所有值变为惰性

时间:2012-08-11 18:08:46

标签: scala lazy-evaluation

或者scala对象中的val默认是懒惰的吗?

无论如何,如果有必要使用val在懒惰的对象中声明lazy,是否可以执行类似

的操作
lazy object SomeObject

或(就像你在c ++中所做的那样)

object A {
lazy:
    val a
    val b
    ...
}

因为我想要懒惰而不必重新标记我val lazy val个{{1}}

4 个答案:

答案 0 :(得分:11)

回答你的第一个问题(默认情况下,scala对象中的val是懒惰的吗?“):不,不完全是,但是对象本身有点懒惰,这可能是懒得够。来自the Scala language specification的5.4(“对象定义”):

  

请注意,实例化对象定义定义的值   懒洋洋。 new m$cls构造函数的评估不是在   对象定义,但是第一次m进行评估   在执行程序期间解除引用(可能永远不会在   全部)。

因此,例如,如果我们有这三个对象:

object X {
  val answer = { println("Here's X's answer!"); 42 }
}

object Y {
  lazy val answer = { println("Here's Y's answer!"); 1 }
}

object Z extends App {
  println("Here we go.")
  println(X)
  println(Y)
  println(X.answer)
  println(Y.answer)
}

然后,当我们运行Z时,我们会看到以下内容:

Here we go.
Here's X's answer!
X$@38d24866
Y$@f1aa6ce
42
Here's Y's answer!
1

因此val中的X并非懒惰,但直到我们第一次使用X时才会对其进行评估。

答案 1 :(得分:1)

简短的回答是:不,它可能(除非你没有用宏做一些疯狂的捣乱)。

答案 2 :(得分:1)

首先,对象已经懒惰地初始化了:

object Y {
  println("aqui")
  val a = 0
}

Y.a  // runs body of Y

其次,如果您对多个val被懒惰地一次初始化感到满意,您可以使用元组中的模式提取:

object X {
  val a = 0
  lazy val (b, c) = {
    println("aqui")
    (1, "hallo")
  }
}

X.a  // runs body of X, initialises strict vals
X.b  // initialises both b and c
X.c

答案 3 :(得分:0)

说到精神错乱(@ om-nom-nom),可能会调整Autoproxy plugin以使其创建惰性包装。那会很有趣。 \

通常,Scala编译器插件允许您执行此操作。您可以通过标记特征或注释标记惰性对象,然后让编译器插件进行重写。编写编译器插件并不是最简单的事情,但它仍然很有趣。