繁体   English   中英

在Scala中键入Erasure

[英]Type Erasure in Scala

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

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的类型的细节可以在运行时使用...

  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警告Abstract type pattern T is unchecked since it is eliminated by erasure 这里发生了什么?

在Scala中,泛型在运行时被擦除,这意味着List[Int]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) =>
    }
  }
}

这个问题的新答案有更多细节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM