Scala延迟val解释
我正在学习Scala的基础知识。我刚刚遇到了Scala延迟val解释,scala,lazy-evaluation,Scala,Lazy Evaluation,我正在学习Scala的基础知识。我刚刚遇到了lazy val的概念。我有以下代码片段,可以在没有错误/警告的情况下工作 案例1 案例2 案例3 我了解案例1和案例2的工作原理。但是我不明白案例3中的代码是如何在没有错误/警告的情况下工作的。当b尚未定义时,Scala如何评估a的值 编辑 我没有在Scala REPL中运行此代码。我已将案例3中的代码保存在名为lazyVal.scala的文件中。我正在使用scala lazyVal.scala执行它。我认为scala解释了文件中的代码 如果我将la
lazy val
的概念。我有以下代码片段,可以在没有错误/警告的情况下工作
案例1
案例2
案例3
我了解案例1和案例2的工作原理。但是我不明白案例3中的代码是如何在没有错误/警告的情况下工作的。当b
尚未定义时,Scala如何评估a
的值
编辑
我没有在Scala REPL
中运行此代码。我已将案例3中的代码保存在名为lazyVal.scala
的文件中。我正在使用scala lazyVal.scala执行它。我认为scala解释了文件中的代码
如果我将lazyVal.scala
中的代码更改为
val a = 10 + b
val b = 5
println(a)
并使用scala lazyVal执行它。scala我确实收到了警告
/Users/varun.risbud/scalaRepo/src/Chapter1/lazyVal.scala:1: warning: Reference to uninitialized value b
val a = 10 + b
^
one warning found
10
另外,如果我更改代码以创建对象并扩展应用程序,它也可以工作
object lazyVal extends App {
val a = 10 + b
lazy val b = 5
println(a)
}
➜ Chapter1 scalac lazyVal.scala
➜ Chapter1 scala lazyVal
15
我的
scala版本
是2.12.1
,如果这有什么区别的话。构造函数中的语句按文本顺序执行,这就是为什么当a
的初始化指代未初始化的b
时会收到警告的原因。以一种你甚至没有得到警告的方式组成一个类是一个常见的错误。(有一个关于这方面的常见问题解答教程。)
本地语句序列中禁止使用相同的文本:
scala> :pa
// Entering paste mode (ctrl-D to finish)
locally {
val a = 10 + b
lazy val b = 5
println(a)
}
// Exiting paste mode, now interpreting.
<console>:13: error: forward reference extends over definition of value a
val a = 10 + b
^
脚本运行程序按以下方式打包代码行:
object X {
def main(args: Array[String]): Unit =
new AnyRef {
val a = 10 + b
lazy val b = 5
println(a)
}
}
如果给它一个带有main
或扩展App
的对象,它不会包装代码,而是直接使用它
这三种配方之间有细微的差别。例如,顶级对象的构造函数作为静态初始值设定项运行;但是,
App
是一种特殊情况,它将初始化器代码作为main
运行。(他们正在摆脱应用程序
,因为它让人困惑。)你只是按照这个顺序在REPL中尝试这些案例吗?如果是这样,则案例3中的b
可能只是案例2中定义的最后一个b
。否则,我将得到一个错误:找不到:值b
。我投票将其作为非主题关闭,因为问题无法再现。@Alec请在问题编辑部分查看它。@Alec实际上,作为脚本问题,它更有趣,因为运行代码的每种方式的语义都不同。脚本运行程序将代码段包装在一个主函数中,在这里您可以看到与从REPL运行不同的错误和行为。更不用说作为应用程序运行了。请提供您在回答中提到的常见问题解答教程的链接
?谢谢您提供的链接和答案。
object lazyVal extends App {
val a = 10 + b
lazy val b = 5
println(a)
}
➜ Chapter1 scalac lazyVal.scala
➜ Chapter1 scala lazyVal
15
scala> :pa
// Entering paste mode (ctrl-D to finish)
locally {
val a = 10 + b
lazy val b = 5
println(a)
}
// Exiting paste mode, now interpreting.
<console>:13: error: forward reference extends over definition of value a
val a = 10 + b
^
scala> :pa
// Entering paste mode (ctrl-D to finish)
object X {
val a = 10 + b
lazy val b = 5
println(a)
}
// Exiting paste mode, now interpreting.
defined object X
scala> X
15
res1: X.type = X$@6a9344f5
object X {
def main(args: Array[String]): Unit =
new AnyRef {
val a = 10 + b
lazy val b = 5
println(a)
}
}