投放问题

问题描述

    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成为案例类。