Dmi*_*try 15 scala initialization traits
请查看以下代码.
trait MyTrait { val myVal : String }
class MyClass extends MyTrait { val myVal = "Value" }
class MyClass2(val myVal: String) extends MyTrait
Run Code Online (Sandbox Code Playgroud)
为什么初始化顺序在MyClass和MyClass2?的情况下有所不同?构造函数MyClass将为
MyClass() {
MyTrait$class.$init$(this);
myVal = value
}
Run Code Online (Sandbox Code Playgroud)
构造函数MyClass2将是
MyClass2(String myVal) { this.myVal = myVal; MyTrait$class.$init$(this) }
Run Code Online (Sandbox Code Playgroud)
我认为初始化顺序应该像MyClass2构造函数那样,两种情况都是一样的.
Dan*_*ral 23
在Scala规范的 5.1节末尾,定义了以下内容:
模板评估.考虑一个模板SC 与 MT 1 与 MT N {}的统计信息.如果这是一个特点(第5.3.3节)的模板,那么它混入评价由语句序列统计数据的评估.如果这不是特征的模板,则其评估包括以下步骤.
- 首先,评估超类构造函数sc(第5.1.1节).
- 然后,在模板的线性化(§5.1.2)的基类到模板的超类由SC表示被混入评估.混合评估在线性化中以相反的顺序发生.
- 最后评估语句序列统计信息.
但请注意,构造函数参数可以由跟随它的任何构造函数使用.因此,需要在它们之前进行初始化.这在第5.1.1节末尾明确说明:
对构造函数调用xc targs的评估...(argsn)包括以下步骤:
- 首先,评估前缀x.
- 然后,参数args1 ,. ..,argsn从左到右进行评估.
- 最后,通过评估c引用的类的模板来初始化正在构造的类 .
这个你没有任何问题,但你最后执行的{stats}确实有问题.最后执行{stats}的原因是它可能引用其祖先类和特征的属性,而祖先显然不知道它的后代.因此,祖先需要在{stats}执行之前完全初始化.
当然,可能你就需要早期初始化.第5.1.6节:早期定义涵盖了这一点.这是你如何写它:
class MyClass extends { val myVal = "Value" } with MyTrait
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3402 次 |
| 最近记录: |