Scala 实现抽象基础并在匿名中混合特征 class

Scala implement abstract base and mix in traits in anonymous class

鉴于:

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

我能做到:

new C with T with U show

但是,它 "feels"(考虑到 Scala 倾向于缩短语法和一般的匿名内容)就像我可以从匿名形式实例化我的混合 class 一样。

的内容
// doesn't work like this at least:
val a = new { def show { print("Anon")}} with T with U
a show

但我完全无法确定我是否只是使用了错误的语法,或者这根本不可能。谁能告诉我应该怎么做,或者如果这绝对不可能?

我认为这是不可能的。

以下两个建议是我能得到的最接近的。

将构造函数与 Mixins 结合使用

以下解决方案需要一个额外的助手class D, 但最终结果看起来几乎和你虚构的语法一样,除了 D 你需要一个额外的字符,你必须 使用圆括号代替花括号:

import scala.language.postfixOps

abstract class A { def show: Unit }
trait T extends A {
  abstract override def show: Unit = {
    print(" T"); super.show; print(" xT")
  }
}
trait U extends A {
  abstract override def show: Unit = {
    print(" U"); super.show; print(" xU")
  }
}
class C extends A {
  def show: Unit = print(" C")
}

new C with T with U show

class D(s: => Unit) extends A {
  def show = s
}

// that's pretty close, isn't it?
val a = new D(print("hurray!")) with T with U
a show

只需将class隐藏在一个块中

如果您只是不想在命名空间中乱扔仅使用一次的 classes,那么只需将 class 包含在一个块中即可:

val a = {
  class D extends A {
    def show = println("NoPollution")
  }
  new D with T with U
}
a show

您想要的是上述 "class-valued compile-time-evaluated-expression" 中的 "eliminate the useless variable D",但我看不出如何做到这一点。

这不就是你想要的吗?

val a = new T with U {override def show { print("Anon")}}

语法与声明新的 class 几乎相同,首先是 extensions/mixins,然后是正文。