gpt4 book ai didi

scala - 覆盖成员和惰性 val

转载 作者:行者123 更新时间:2023-12-01 22:38:53 26 4
gpt4 key购买 nike

我找到了 this explanation关于如何使用 lazy val 将覆盖的成员值传播到父类(super class)构造函数。不幸的是,这篇文章没有解释为什么会这样。

我理解非惰性值不能被赋值两次,因此, super 构造函数中没有可用的值,因为必须跳过父类(super class)构造函数中的值赋值,以免将变量锁定为另一个值。但是,println 语句(在 super 构造函数中执行,即在分配新惰性值之前)如何知道这个新值?我对执行顺序感到困惑吗?还是 println 以某种方式仅在构造对象后评估其参数?

最佳答案

这很简单。您只需要注意所有字段和惰性字段都是 getter 方法。

val getter 返回 private[this] 字段的值。 private[this] 字段赋值位于主构造函数中:

class Test {
val field = 1
}

意思是这样的:

class Test {
private[this] val _field: Int = _
def field = _field

{ // constructor
_field = 1
}
}

因此在构造函数 field 返回默认值之前。

lazy val 使用双重检查锁评估代码块并返回结果:

class Test {
lazy val field = 1
}

意思是这样的:

class Test {
private[this] val _field: Int = _
@volatile private[this] val _flag: Boolean = _

def field = {
if (! _flag) {
synchronized {
if (! _flag) {
_field = 1 // code block
_flag = true
}
}
}

_field
}
}

所以 lazy val 与构造函数无关,你将在构造函数之前和之后得到相同的结果。

您可以使用 scalac -Xprint:mixin test.scala 进行检查。

关于scala - 覆盖成员和惰性 val,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18047079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com