scala 类型擦除 - 匹配案例类

kcr*_*ris 1 scala pattern-matching type-erasure

我正在阅读有关类型擦除的内容,在这里

case class Thing[T](value: T)

def processThing(thing: Thing[_]) = {
  thing match {
    case Thing(value: Int) => "Thing of int"         //isn't thing Thing[_] anymore?
    case Thing(value: String) => "Thing of string"   //isn't thing Thing[_] anymore?
    case Thing(value: Seq[Int]) => "Thing of Seq[Int]"         //value=Seq[_] really
    case Thing(value: Seq[String]) => "Thing of Seq[String]"   //value=Seq[_] really
    case _ => "Thing of something else"
  }
}
println(processThing(Thing(Seq(1,2,3))))          //type erased, I get it
println(processThing(Thing(Seq("hello", "yo"))))  //type erased, I get it
println(processThing(Thing(1)))                   //why is this working?
println(processThing(Thing("hello")))             //why is this working?
Run Code Online (Sandbox Code Playgroud)

我理解为什么 Seq[Int] 和 Seq[String] 没有正确识别,在运行时两者都像 Seq[Object] 一样。

但是,我不明白为什么前两个示例有效:为什么 Thing[Int] 和 Thing[String],两者都是 Thing[T] ,没有遇到 Seq[T] 所遇到的相同问题......

为什么 Thing[Seq[T]] 被类型擦除但 Thing[T] (T=Int, String) 却没有?

有人能解释一下这是怎么回事吗?谢谢

Lui*_*rez 5

你是对的,在运行时两者Thing(1)都会Thing("Hello")被擦除到同一个类Thing

因此,如果你这样做:

thing match {
  case _: Thing[Int] => foo
  case _: Thing[String] => bar
}
Run Code Online (Sandbox Code Playgroud)

您会看到您期望的行为。

但是,您的模式匹配正在做一些不同的事情,它提取内部的值thing,然后对其执行类检查。值的类信息是自行保留的,因此您可以区分Int,StringSeq,但您看不到 the 的类型参数是什么Seq
但是,您可以尝试检查Seq...but的第一个元素这仍然不够,因为第一个元素可能是 a Dog,第二个元素可能是 a,Cat因为它是 a,Seq[Animal]并且该检查比前面的检查更不安全,因为可能Seq为空。