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

scala中trait中使用的抽象值是否有问题?,scala,traits,Scala,Traits,我有 Intellij IDEA代码检查警告我“trait中使用了抽象值”。一切都很好。在特质中有抽象的价值有什么不对吗?如果是这样,我应该如何指定trait的所有扩展程序必须定义一个方法属性?这意味着以下奇怪之处: trait Invoker { val method: Method } 因此,如您所见,i被初始化为它的默认值(null,对于AnyRef),然后在C中被构造函数最终覆盖。(def声明将立即重新引用。) 为了避免这种情况,如果可能的话,必须将val初始化放在构造函数的开头

我有


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

这意味着以下奇怪之处:

trait Invoker {
  val method: Method
}
因此,如您所见,
i
被初始化为它的默认值(
null
,对于
AnyRef
),然后在
C
中被构造函数最终覆盖。(
def
声明将立即重新引用。)

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


在以下情况下,会出现额外的奇怪(以及如何解决)

考虑

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
现在我们似乎不走运了;在我们的超类
D
尝试打印它们之前,我们似乎没有机会初始化
vali
defj
。 为了解决这个问题,我们必须使用早期定义(§5.1.6):


而且它有效

在特质中使用抽象val有很多很好的理由。不幸的是,IntelliJ IDEA并没有区分它们,只是警告人们不要普遍使用它们。实际上,这意味着IntelliJ IDEA警告将被忽略。

IntelliJ更进一步,如果您在该警告上展开工具提示,您将发现:“trait中的抽象值和变量可能会在初始化过程中导致错误。”有时这些工具提示甚至引用Scala Lang.Spec。如果您对抽象VAL感到满意,那么您可以转到“设置/检查/Scala/abstract value in trait”并降低警告级别。但完整的警告信息是公平的。毕竟,这是一个警告,而不是一个错误。@pedrofurla:正确代码中不可避免的警告对优秀程序员来说是一个烦恼,但对于较弱的程序员来说,这是一个打破窗口的邀请,让他们在代码中留下真正的问题。这不应该是一个警告。Tony是对的,他太固执己见了,IDE不会发出这样的警告。请参阅以获取投票解决此问题的问题。好的程序员必须知道如何解释警告。在正确的程序中出现错误是一件令人烦恼的事。我相信当你有其他问题要解决时,在你的头脑中做这个回溯是有点乏味的。假设我们使用scala是因为我们喜欢简单。我将选择启用此警告。评论比较晚,但由于仍在链接:问题不是抽象的
val
,而是
C
中的实现。如果将
A
中的
i
更改为
def
,则会得到相同的结果。
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
class C extends {
  val i = "i"
  def j = "j"
} with D

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