如何初始化从亚型特质的价值?(How to initialize the value from tr

2019-08-19 01:02发布

如果我写的:

trait T {
  val t = 3
  val u = 1::t::Nil
}

class U extends T {
  override val t = 2
}

(new U).u

它显示了这一点。

List(1, 0)

我应该如何改变上面的代码,使其显示如下:

List(1, 2)

override val t设置的值tu的特质T

Answer 1:

要做到这一点的方法之一是延缓评估udeflazy val如下:

trait T {
  def t = 3
  def u = 1::t::Nil
}

class U extends T {
  override def t = 2
}

(new U).u

要么

trait T {
  val t = 3
  lazy val u = 1::t::Nil
}

class U extends T {
  override val t = 2
}

(new U).u 

它们的区别如下:

  • val使初始化期间的表达评估
  • def使得每次的表达评估u用于
  • lazy val使得它在第一次评估u的使用和缓存结果


Answer 2:

尝试使用早期的初始化:

scala> trait T {
     |   val t = 3
     |   val u = 1::t::Nil
     | }
defined trait T

scala> class U extends {
     | override val t = 2;
     | } with T
defined class U

scala> (new U).u
res1: List[Int] = List(1, 2)

例如参见这里关于早期初始化的更多信息。



Answer 3:

所有斯卡拉声明风格只是一种假象。 Scala是建立在JVM和工作像Java。

Evetything是一类和应该独立于它的使用(Java是不C ++和支持增量生成与其利弊)。 各性状都有自己的初始化代码和多性状类运行相应的初始化代码逐个。 如果您使用的是只有在子类中比它的价值将为空初始化过程中设置一些声明AnyRef。

我守护自己与specifing约定规则:每VAL应该是最终或懒惰( 为什么在非final类使用普通VAL )。 所以,我不关心初始化顺序,并且还可以假装我使用的声明性语言。

另外我使用的选项-Xcheckinit :运行时检查添加到现场存取。



文章来源: How to initialize the value from trait in subtype?
标签: scala traits