Scala lazy val 解释
Scala lazy val interpretation
我正在学习 Scala 基础知识。我刚刚遇到 lazy val
概念。我有以下代码片段,无需 errors/warnings
案例一
lazy val a = 10 + b
lazy val b = 5
println(a)
案例二
lazy val a = 10 + b
val b = 5
println(a)
案例三
val a = 10 + b
lazy val b = 5
println(a)
我了解 case 1 & 2
的工作原理。但是我不明白 case 3
中的代码在没有 error/warning 的情况下是如何工作的。当 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 version
是 2.12.1
如果这有什么不同的话。
构造函数中的语句按文本顺序执行,这就是为什么当 a
的初始化引用未初始化的 b
时会收到警告。以一种您甚至没有收到警告的方式编写 class 是一个常见的错误。 (有一个常见问题解答教程。)
在本地语句序列中禁止使用相同的文本:
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
^
作为 class 或对象的成员,惰性成员被计算 "on demand",而 a
在构造期间被计算。
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
脚本 运行ner 以这种方式打包您的代码行:
object X {
def main(args: Array[String]): Unit =
new AnyRef {
val a = 10 + b
lazy val b = 5
println(a)
}
}
如果你给它一个带有 main
或扩展 App
的对象,它不会包装代码,而是直接使用它。
三种配方之间存在细微差别。例如,顶层对象的构造函数是 运行 作为静态初始化器;但是 App
是 运行 初始化代码的特殊情况,如 main
。 (他们正在摆脱 App
因为它令人困惑。)
我正在学习 Scala 基础知识。我刚刚遇到 lazy val
概念。我有以下代码片段,无需 errors/warnings
案例一
lazy val a = 10 + b
lazy val b = 5
println(a)
案例二
lazy val a = 10 + b
val b = 5
println(a)
案例三
val a = 10 + b
lazy val b = 5
println(a)
我了解 case 1 & 2
的工作原理。但是我不明白 case 3
中的代码在没有 error/warning 的情况下是如何工作的。当 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 version
是 2.12.1
如果这有什么不同的话。
构造函数中的语句按文本顺序执行,这就是为什么当 a
的初始化引用未初始化的 b
时会收到警告。以一种您甚至没有收到警告的方式编写 class 是一个常见的错误。 (有一个常见问题解答教程。)
在本地语句序列中禁止使用相同的文本:
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
^
作为 class 或对象的成员,惰性成员被计算 "on demand",而 a
在构造期间被计算。
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
脚本 运行ner 以这种方式打包您的代码行:
object X {
def main(args: Array[String]): Unit =
new AnyRef {
val a = 10 + b
lazy val b = 5
println(a)
}
}
如果你给它一个带有 main
或扩展 App
的对象,它不会包装代码,而是直接使用它。
三种配方之间存在细微差别。例如,顶层对象的构造函数是 运行 作为静态初始化器;但是 App
是 运行 初始化代码的特殊情况,如 main
。 (他们正在摆脱 App
因为它令人困惑。)