还是val
默认情况下 scala 对象中的 s 是惰性的?
无论如何,如果有必要val
通过 using 在对象中声明 a lazy
,是否可以执行类似的操作
lazy object SomeObject
或(就像你在 C++ 中所做的那样)
object A {
lazy:
val a
val b
...
}
因为我想偷懒,不必重新标记我所有的val
slazy val
还是val
默认情况下 scala 对象中的 s 是惰性的?
无论如何,如果有必要val
通过 using 在对象中声明 a lazy
,是否可以执行类似的操作
lazy object SomeObject
或(就像你在 C++ 中所做的那样)
object A {
lazy:
val a
val b
...
}
因为我想偷懒,不必重新标记我所有的val
slazy val
回答您的第一个问题(“ val
scala 对象中的 s 默认情况下是惰性的吗?”):不,不完全是,但对象本身有点惰性,这可能已经足够惰性了。从Scala 语言规范的 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
inX
不是懒惰的,但直到我们第一次使用它才被评估X
。
首先,对象已经被延迟初始化:
object Y {
println("aqui")
val a = 0
}
Y.a // runs body of Y
其次,如果您对多个 s一次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
简短的回答是:不,这是不可能的(除非你没有用宏做一些疯狂的运算)。
说到精神错乱(@om-nom-nom),也许可以调整Autoproxy 插件,使其创建惰性包装器。那将是……有趣。\
通常,Scala 编译器插件可以让您执行此操作。您可以通过标记特征或注释标记惰性对象,然后让编译器插件进行重写。编写编译器插件并不是最简单的事情,但它仍然很有趣。