问题描述
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是协变类型。我想念什么吗?
谢谢
解决方法
在Scastie,它不可复制为https://scastie.scala-lang.org/tCD4HahgTqO4WTnlGcfWqQ,但可复制为https://scastie.scala-lang.org/L46PWLF2S5i4d1IGoT6UuQ
只有在我为ClassCastException
删除了lazy
的情况下,我才能在本地复制Def#hashCode
。
协方差无关。
在this.asInstanceOf[Product]
中,您尝试将Def
的{{1}}强制转换为this
。创建Product
时,它是当前new N1()
的{{1}}。
Def
作为类this
的值不能转换为new N1()
,因为N1
不扩展Product
。
在Scala中,默认情况下,类不扩展N1
,案例类则不扩展。
要修复Product
,就足以使Product
成为案例类。