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

标签 scala traits 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

但是,它“感觉”(考虑到 Scala 通常倾向于缩短语法和匿名内容)就像我可以从匿名形式实例化我的混合类。类似于

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

但我完全无法确定我是否只是使用了错误的语法,或者这根本不可能。有人可以告诉我应该如何做到这一点,或者这绝对不可能吗?

最佳答案

我认为这是不可能的。

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

将构造函数与 Mixins 一起使用

以下解决方案需要额外的辅助类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

只需将类隐藏在 block 中

如果您只是不想在命名空间中放置只使用一次的类,那么只需将该类放在一个 block 中即可:

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

你想要的是“消除上面的“类值编译时评估表达式”中无用的变量D”,但我不知道如何做到这一点。

关于Scala 实现抽象基类并在匿名类中混合特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48369018/

相关文章:

c# - Linq Lambda 从聚合中获取两个属性作为字符串

scala - 我可以创建没有 "extends"的 GUI吗

scala - Spark : How do I pass a PartialFunction to a DStream?

scala - 在 Scala 中定义子类型的排序

swiftmailer - Swiftmailer 的 Silex 特征。 fatal error :调用未定义的方法 Silex\Application::mail()

java - Scala:将 java 接口(interface)移植到 scala

c# - 在 HtmlHelper 扩展方法中使用匿名对象

scala - Spark中的内部map函数

rust - 如何更好地存储字符串以避免出现许多克隆?

scala - 早期初始化程序 `new {} with SomeTrait` 失败