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

是否可以使用一个关键字使scala对象中的所有值变为惰性,scala,lazy-evaluation,Scala,Lazy Evaluation,或者scala对象中的vals在默认情况下是惰性的 无论如何,如果有必要使用lazy在对象lazy中声明val,是否可以执行以下操作 lazy object SomeObject 或者(就像在c++中一样) 因为我想成为一个懒惰的人,而不必重新标记我所有的valslazy val简短的回答是:不,它是不可能的(除非你没有对宏做一些疯狂的处理)。说到疯狂(@om nom nom),可能会修改它以创建懒惰的包装器。那将是。。。有趣\ 通常,Scala编译器插件允许您执行此操作。您可以通过标记特征或

或者scala对象中的
val
s在默认情况下是惰性的

无论如何,如果有必要使用
lazy
在对象lazy中声明
val
,是否可以执行以下操作

lazy object SomeObject
或者(就像在c++中一样)


因为我想成为一个懒惰的人,而不必重新标记我所有的
val
s
lazy val

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

说到疯狂(@om nom nom),可能会修改它以创建懒惰的包装器。那将是。。。有趣\


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

回答第一个问题(“scala对象中的
val
s默认是懒惰的吗?”):不,不完全是,但对象本身有点懒惰,这可能已经够懒了。第5.4节(“对象定义”)中:

注意,对象定义定义的值是实例化的 懒洋洋地。
新的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

因此,
X
中的
val
不是惰性的,但是直到我们第一次使用
X

时才对其进行评估首先,对象已经惰性地初始化:

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

Y.a  // runs body of Y
第二,如果您对同时延迟初始化多个
val
s感到满意,则可以使用元组中的模式提取:

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

我想在解析器阶段之后添加lazy标志几乎是微不足道的。。。根据我的经验,编写第一个编译器插件的学习曲线相当陡峭。然而,实际任务确实应该相当容易。
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