Scala 中的类型擦除

2024-03-16

我对这里发生的事情感到很困惑:

import scala.collection.immutable._

object Main extends App {
  sealed trait Node

  sealed trait Group

  case class Sheet(
    val splat: String,
    val charname: String, 
    val children: ListMap[String, Node],
    val params0: ListMap[String, Param], //params0 to separate sheet-general parameters

    val note: Option[Note]
    ) extends Node with Group

  case class Attributes(val name: String) extends Node with Group

  case class Param(val name: String, val value: String) extends Node
  case class Note(val note: String) extends Node

我有三个版本的替换函数 - 最后一个是我实际上正在尝试编写的版本,其他版本只是调试。

  class SheetUpdater(s: Sheet) {    
    def replace1[T <: Group](g: T): Unit = {
      s.children.head match {
        case (_, _:Sheet) =>
        case (_, _:Attributes) =>
      }
    }
  }

这个版本没有发出警告,所以显然我可以访问的类型s.children在运行时。

  class SheetUpdater(s: Sheet) {
    def replace2[T <: Group](g: T): Unit = {
      g match {
        case _:Sheet =>
        case _:Attributes =>
      }
    }
  }

这个版本也没有,所以显然细节g的类型是also在运行时可用...

  class SheetUpdater(s: Sheet) {
    def replace3[T <: Group](g: T): Unit = {
      s.children.head match {
        case (_, _:T) => //!
        case (_, _:Attributes) =>
      }
    }
  }

...但即便如此,这最终还是让我陷入了可怕的境地Abstract type pattern T is unchecked since it is eliminated by erasure警告。这里发生了什么?


在Scala中,泛型在运行时被擦除,这意味着运行时类型List[Int] and List[Boolean]其实是一样的。这是因为 JVM 作为一个整体删除了泛型类型。所有这一切都是因为 JVM 希望在泛型首次引入时保持向后兼容......

Scala 有一种方法可以解决这个问题,使用ClassTag,这是一个隐式参数,然后可以与您正在使用的任何泛型一起使用。

你可以想到: ClassTag作为传递泛型的类型作为参数。 (它是传递隐式参数类型的语法糖ClassTag[T].)

import scala.reflect.ClassTag

class SheetUpdater(s: Sheet) {
  def replace3[T <: Group : ClassTag](g: T): Unit = {
    s.children.head match {
      case (_, _:T) => //!
      case (_, _:Attributes) =>
    }
  }
}

这个问题的新答案有更多细节。 https://stackoverflow.com/questions/1094173/how-do-i-get-around-type-erasure-on-scala-or-why-cant-i-get-the-type-paramete?rq=1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 中的类型擦除 的相关文章

随机推荐