Scala初始化行为 [英] Scala initialization behaviour

查看:115
本文介绍了Scala初始化行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请查看以下代码.

trait MyTrait { val myVal : String }

class MyClass extends MyTrait { val myVal = "Value" }

class MyClass2(val myVal: String) extends MyTrait 

MyClassMyClass2的情况下,为什么初始化顺序不同? MyClass的构造函数将为

Why does the initialization order differ in case of MyClass and MyClass2? The constructor of MyClass will be as

MyClass() {
  MyTrait$class.$init$(this);
  myVal = value
}

MyClass2的构造函数将是

MyClass2(String myVal) { this.myVal = myVal; MyTrait$class.$init$(this) }

我认为初始化顺序应该与MyClass2的构造函数相同,这两种情况都是相同的.

I think the initialization order should be as MyClass2's constructor does, the same for both cases.

推荐答案

Scala规范,定义如下:

模板评估.考虑模板 sc 具有 mt 1 具有 mt n {stats} .如果这是模板 一个特征(第5.3.3节),然后将其 mixin评估包含一个评估- 语句序列的确定 统计资料.如果这不是模板的模板 特质,则其评估包括 以下步骤.

Template Evaluation. Consider a template sc with mt 1 with mt n {stats}. If this is the template of a trait (§5.3.3) then its mixin-evaluation consists of an eval- uation of the statement sequence stats. If this is not a template of a trait, then its evaluation consists of the following steps.

  • 首先,对超类构造函数sc进行评估(第5.1.1节).
  • 然后,模板线性化(第5.1.2节)中的所有基类 表示为模板的超类 通过sc进行混合评估. 反向混合素评估 出现顺序 线性化.
  • 最后评估语句序列统计信息.
  • First, the superclass constructor sc is evaluated (§5.1.1).
  • Then, all base classes in the template’s linearization (§5.1.2) up to the template’s superclass denoted by sc are mixin-evaluated. Mixin-evaluation hap- pens in reverse order of occurrence in the linearization.
  • Finally the statement sequence stats is evaluated.

但是,请注意,其后的任何构造函数都可以使用构造函数参数.因此,需要在它们之前进行初始化.在第5.1.1节的末尾对此进行了明确说明:

Note, however, that the constructor parameters may be used by any constructors that follow it. Therefore, it needs to be initialized before them. This is made explicit at the end of section 5.1.1:

对构造函数的评估 调用 x.c targs. . .(argsn)由以下内容组成 步骤:

An evaluation of a constructor invocation x.c targs. . .(argsn) consists of the following steps:

  • 首先,评估前缀 x .
  • 然后,参数 args1,. . . ,argsn 从左到右求值 是的.
  • 最后,通过评估 所引用类的模板 c .
  • First, the prefix x is evaluated.
  • Then, the arguments args1 , . . . , argsn are evaluated from left to right.
  • Finally, the class being constructed is initialized by evaluating the template of the class referred to by c.

您没有任何问题,但是您确实有问题,最后执行 {stats} .最后执行 {stats} 的原因是它可以引用其祖先类和特征的属性,而祖先显然不了解其后代.因此,在执行 {stats} 之前,祖先需要完全初始化.

This you don't have any problem with, but you do have a problem with {stats} being executed last. The reason why {stats} is executed last is that it may reference attributes of its ancestor classes and traits, whereas the ancestors obviously have no knowledge about its descendants. Therefore, the ancestors need to be fully initialized before {stats} gets executed.

当然,您可能要做需要尽早初始化.第5.1.6节:早期定义中对此进行了介绍.这是您的写法:

Of course, it is possible that you do need early initialization. This is covered by section 5.1.6: Early Definitions. Here's how you'd write it:

class MyClass extends { val myVal = "Value" } with MyTrait

这篇关于Scala初始化行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆