Scala自身类型特质实例化

3

在Scala中Trait类似于Java中的接口或抽象类。因此,无法直接从Trait中获取实例。但是我发现了一种实例化Trait的方法。下面是我所做的:

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

and the following:

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版本。它们全部只使用了trait,没有任何class。

trait如何以这种方式工作呢?


1
其实比那更简单。new B {} - jwvh
1个回答

6
这个实例化类似于Java的匿名类实例化,因此当使用new Tweeter with User时,实际上为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,用于如何使用 self type 实现依赖注入

那么,“new A with B”只是“new Object extends A with B”的一种语法糖吗?或者像使用case class一样? - Jeff Xu
@JeffXu 是的,它创建了一个新的类(匿名类),该类从 ABextends 继承。 - chengpohi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接