【发布时间】:2021-01-16 12:26:51
【问题描述】:
import scala.annotation.unchecked.uncheckedVariance
import scala.collection.immutable.Queue
import scala.collection.mutable.ListBuffer
abstract class Exp[+T:Manifest] { // constants/symbols (atomic)
def tp: Manifest[T @uncheckedVariance] = manifest[T] //invariant position! but hey...
}
case class Sym[+T:Manifest](val id: Int) extends Exp[T] {
}
abstract class Def[+T] { // operations (composite)
override final lazy val hashCode = scala.runtime.ScalaRunTime._hashCode(this.asInstanceOf[Product])
}
abstract class Stm
case class TP[+T](sym: Sym[T], rhs: Def[T]) extends Stm
abstract class Trial{
}
class M1() extends Trial{}
class M2() extends Trial{}
class N1() extends Def[M1]{}
class N2() extends Def[M2]{}
TP(Sym[M1]{4},new N1())
这会产生以下错误:
scala> TP(Sym[M1]{4},new N1()) java.lang.ClassCastException: 类 N1 不能转换为 scala.Product 类(N1 在未命名的模块中 加载程序 scala.tools.nsc.interpreter.IMain$TranslatingClassLoader @2098d37d; scala.Product 位于加载程序“bootstrap”的未命名模块中)
在 Def.hashCode$lzycompute(:13) 在 Def.hashCode(:13) 在 java.base/java.lang.Object.toString(Object.java:246) 在 java.base/java.lang.String.valueOf(String.java:2951) 在 java.base/java.lang.StringBuilder.append(StringBuilder.java:168) 在 scala.collection.IterableOnceOps.addString(IterableOnce.scala:1194)
在 scala.collection.IterableOnceOps.addString$(IterableOnce.scala:1186)
在 scala.collection.AbstractIterator.addString(Iterator.scala:1279)
在 scala.collection.IterableOnceOps.mkString(IterableOnce.scala:1136) 在 scala.collection.IterableOnceOps.mkString$(IterableOnce.scala:1134) 在 scala.collection.AbstractIterator.mkString(Iterator.scala:1279)
在 scala.runtime.ScalaRunTime$._toString(ScalaRunTime.scala:159) 在 TP.toString(:18) 在 scala.runtime.ScalaRunTime$.inner$1(ScalaRunTime.scala:261) 在 scala.runtime.ScalaRunTime$.stringOf(ScalaRunTime.scala:266) 在 scala.runtime.ScalaRunTime$.replStringOf(ScalaRunTime.scala:274) 在 .lzycompute(:8) ... 28 省略
我期待一个 TP[Trial] 类型的对象,发生了什么?因为 Sym 和 Def 是协变类型。我错过了什么吗?
谢谢
【问题讨论】:
-
这与
N1和N2不能被this.asInstanceOf[Product]转换成Product有什么关系?把N1和N2改成case class-es,然后就可以无异常运行了。这一切看起来相当复杂,比相关实体的名称所暗示的要复杂得多。您介意简要描述一下您要完成的工作吗? -
@AndreyTyukin,我真的不明白为什么 N1 和 N2 必须是案例类,你能解释一下吗?
-
Product 上的文档基本上列出了该特征的所有常见实现——本质上是元组和案例类。由于
N1显然不是一个元组,如果它不应该导致任何ClassCastExceptions,它可能应该是一个case class。你对Product类型转换有什么期望?
标签: scala types casting subclass covariant