scala - Scala 中 trait 中使用的抽象值有什么问题吗?

标签 scala traits

我有

trait Invoker {
  val method: Method
}

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

最佳答案

这意味着以下奇怪之处:

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

所以,正如你所看到的 i在它最终被 null 中的构造函数覆盖之前被初始化为它的默认值( AnyRef for 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 idef j在我们的父类(super class)之前 D尝试打印它们。
为了解决这个问题,我们必须使用早期定义(§5.1.6 Scala reference):
class C extends {
  val i = "i"
  def j = "j"
} with D

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

它有效!

关于scala - Scala 中 trait 中使用的抽象值有什么问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7846119/

相关文章:

scala - 倾斜的窗口函数和 Hive 源分区?

scala - 如何在 spark RetryingBlockFetcher IOException 中设置 remoteHost

rust - 需要 Rust 特征边界中的交换操作

swing - 如何使用 SuperMixin 创建 Scala swing 包装类?

groovy - 特征中的私有(private)抽象声明给出静态上下文错误

java - 如何使用 Play Framework 通过 SSL 连接到远程 MySQL 数据库?

Scala、JPA 和可为 null 的字段

scala - 如何使用 spark-shell 导入自己的 scala 包?

c++ - 可以创建任意类型的 constexpr 链表吗?

Scala:获取混合特征的类的名称