【问题标题】:How to copy a case class and add a mixin?如何复制案例类并添加mixin?
【发布时间】:2018-02-03 21:56:28
【问题描述】:

我想要一个可以随意扩展为不同类型的基本案例类。我以前有这样的工作,但我一定搞砸了,因为现在我遇到了编译错误。

trait JobLike

case class Task(name: String) {

  def as[T <: JobLike]: Task with T = new Task(this.name) with T

}

问题是,这给了我这样的编译器错误:

java.lang.UnsupportedOperationException: addChild inapplicable for type T
at scala.reflect.internal.Symbols$Symbol.addChild(Symbols.scala:1835)
at scala.tools.nsc.typechecker.Namers$Namer.$anonfun$templateSig$1(Namers.scala:1119)
at scala.tools.nsc.typechecker.Namers$Namer.templateSig(Namers.scala:1107)
at scala.tools.nsc.typechecker.Namers$Namer.classSig(Namers.scala:1178)
at scala.tools.nsc.typechecker.Namers$Namer.memberSig(Namers.scala:1788)
at scala.tools.nsc.typechecker.Namers$Namer.typeSig(Namers.scala:1751)
at scala.tools.nsc.typechecker.Namers$Namer$MonoTypeCompleter.completeImpl(Namers.scala:836)
...
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:82)
at scala.tools.nsc.MainGenericRunner.run$1(MainGenericRunner.scala:85)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:101)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)</code>

我发誓,我昨天有一些工作基本上就是这样做的,但现在它抛出了这个错误。

【问题讨论】:

  • 我找不到可以成功编译的编译器版本,但通常它应该以T is not a class type 失败,所以这看起来像是一种回归。考虑在github.com/scala/bug/issues 提交错误报告

标签: scala case-class


【解决方案1】:

您设法遇到了编译器错误!虽然这肯定是一个问题,应该报告,但问题是你的代码无论如何都是不可能的,最好是它崩溃并将你带到这里,而不是“工作”并做一些可怕的错误。因为T 可以是JobLike 的任何子类型,所以根本无法在编译时混合它。我可以很好地做trait Boom extends JobLike { def something: Int }; task.as[Boom],然后task 无法创建Boom,因为something 没有实现。

您可以提供asJobLike: Task with JobLike,而不是一般的as[T]: Task with T,这是完全可能的。 (请注意,不鼓励创建case classes 的子类型,因此您可能需要创建一个新类。原因是它破坏了equals 的自反性。)

你可以做的一些相当肮脏的事情是打电话给(new Task(this.name) with JobLike).asInstanceOf[Task with T]asInstanceOf 仅检查 with 中最左边的类型的转换,因此这不会立即使用 ClassCastException(您也可以这样做 "a".asInstanceOf[String with Int].)。只要T 没有成员,它通常会起作用(模数asInstanceOf[T]false)。

您还可以做的一些可怕的事情是使用运行时反射来动态创建所需的类。整个伎俩是肮脏和完全不安全的,所以我不会在这里说,但有一个link

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-04
    • 1970-01-01
    • 2013-08-02
    • 2015-05-14
    • 1970-01-01
    相关资源
    最近更新 更多