scala self type trait instantiation

时间:2018-06-07 03:22:52

标签: scala

scala中的特性类似于Java或抽象类中的接口。因此,不可能直接从特征中获取实例。但是,我找到了一种实例化特征的方法。这是我做的:

trait B {
  def bId = 1
}

trait A { self: B =>
  def aId = 2
}

val a = new A with B // The type of a is "A with B", a's value is $anon$1@6ad16c5d

以及以下内容:

trait User {
  def name: String
}

trait DummyUser extends User {
  override def name: String = "foo"
}

trait Tweeter { self: User =>
  def tweet(msg: String) = println(s"$name: $msg")
}

val t = new Tweeter with User // This doesn't compile
val t = new Tweeter with User with DummyUser // This does work!
// t: Tweeter with User with DummyUser = $anon$1@72976b4
t.tweet("hello")  // result is: "foo: hello"

这两段代码都在使用Scala 2.12。在所有这些中,只有特征!完全没有课。

特质如何以这种方式运作?

1 个答案:

答案 0 :(得分:6)

此实例化,例如 Java Anonymous Classes实例化,因此当new Tweeter with User实际创建新的匿名实例 for Tweeter with User 匿名类

并且new Tweeter with User因此无法编译,因为它失去了name方法的实现。实际上你需要实现它:

  val t = new Tweeter with User {
    override def name: String = "hello world"
  }

对于new Tweeter with User with DummyUser,您只需将其说明为new Tweeter with DummyUser,因为DummyUserUser的子类型。

Scala 中有cake pattern,了解如何使用自我类型来实施依赖注入