我在 Scala 中有一个 A 类,就像这样:
class A {
val a = 3
lazy val b = 2
println("a = " + a)
println("b = " + b)
}
接下来,我将这个类扩展到另一个 B 类:
class B extends A {
override val a = 4
override lazy val b = 3
}
现在,当我创建一个对象时class B
,我得到以下输出:
a = 0 //the default value of int is zero `0` in Scala
b = 3
而我期望的输出是:
a = 3
b = 2
我的问题是如何println()
功能于class A
了解中定义的值class B
,但仅限于b
而不是a
?
docs.scala-lang.org - 教程 - 初始化顺序 https://docs.scala-lang.org/tutorials/FAQ/initialization-order.html提供了完整的解释。
为了看得更清楚,我们在课堂上打印同样的东西B
就像在课堂上一样A
:
class A {
val a = 3
lazy val b = 2
println("A: a = " + a)
println("A: b = " + b)
}
class B extends A {
override val a = 4
override lazy val b = 3
println("B: a = " + a)
println("B: b = " + b)
}
在这种情况下,new B()
产生:
A: a = 0
A: b = 3
B: a = 4
B: b = 3
非惰性的初始化顺序val
变量由下式给出:
在缺乏“早期定义”(见下文)的情况下,初始化
strict vals 按以下顺序完成。
- 超类在子类之前完全初始化。
- 否则,按声明顺序。
Thus A
之前已完全初始化B
.
But val
不能多次初始化。所以 Scala 内部给它一个默认值(0
for an Int
, null
for a String
, ..) 当首先处理超类时A
.
因此它打印0
一开始(初始化时A
) 进而4
(初始化时B
).
使用lazy vals是提出的解决方案scaladoc https://docs.scala-lang.org/tutorials/FAQ/initialization-order.html来绕过这个限制。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)