scala中trait中使用的抽象值是否有问题?

时间:2011-10-21 07:12:28

标签: scala traits

我有

trait Invoker {
  val method: Method
}

Intellij IDEA代码检查警告我“特征中使用的抽象值”。一切都很好。在特质中使用抽象值有什么问题吗?如果是这样,我应该如何指定特征的所有扩展器必须定义方法属性?

2 个答案:

答案 0 :(得分:38)

这意味着以下奇怪之处:<​​/ p>

trait A {
  val i: String
  def j: String
}

class C extends A {
  println ("val i = " + i)
  println ("def j = " + j)

  val i = "i"
  def j = "j"
}

val c = new C
// prints
// val i = null
// def j = j

因此,您可以看到inull中被构造函数最终覆盖之前,已初始化为默认值(AnyRef的{​​{1}})。 (C声明会立即重新引用。)

为了避免这种情况,如果可能的话,必须将def初始化放在构造函数的开头。


以下情况中的其他奇怪(以及如何解决)

考虑

val

现在我们似乎运气不好;在我们的超类trait A { val i: String def j: String } abstract class D extends A { println ("val i = " + i) println ("def j = " + j) } class C extends D { val i = "i" def j = "j" } val c = new C // prints // val i = null // def j = null 尝试打印它们之前,我们似乎没有机会初始化val i def j。 为了解决这个问题,我们必须使用早期定义(§5.1.6Scala reference):

D

它有效!

答案 1 :(得分:6)

在特征中使用抽象val有很多充分的理由。不幸的是,IntelliJ IDEA并没有区分它们,只是简单地警告它们不受普遍使用。实际上,这意味着忽略了IntelliJ IDEA警告。