Scala 用泛型Case类理解擦除

Scala 用泛型Case类理解擦除,scala,erasure,Scala,Erasure,对于以下案例类: scala> case class Foo[T](name: String) {} defined class Foo scala> val foo = Foo[Int]("foo") foo: Foo[Int] = Foo(foo) 为什么Scala会像我想的那样让我匹配Foo[Int]?Int不是被擦除了吗 scala> foo match { | case _: Foo[Int] => "foo" | case _

对于以下案例类:

scala> case class Foo[T](name: String) {}
defined class Foo

scala> val foo = Foo[Int]("foo")
foo: Foo[Int] = Foo(foo)
为什么Scala会像我想的那样让我匹配
Foo[Int]
Int
不是被擦除了吗

scala> foo match { 
     |   case _: Foo[Int] => "foo"
     |   case _        => "bar"
     | }
res2: String = foo
但是当包含另一个模式匹配案例时,它会显示编译时错误

scala> foo match { 
     |  case _: Foo[String] => "string"
     |  case _: Foo[Int]    => "int"
     |  case _              => "other"
     | }
<console>:12: warning: non-variable type argument String in type pattern Foo[String] is unchecked since it is eliminated by erasure
               case _: Foo[String] => "string"
                       ^
    <console>:12: error: pattern type is incompatible with expected type;
     found   : Foo[String]

 required: Foo[Int]
               case _: Foo[String] => "string"
                       ^
scala>foo-match{
|大小写:Foo[String]=>“String”
|案例:Foo[Int]=>“Int”
|案例=>“其他”
| }
:12:警告:类型模式Foo[String]中的非变量类型参数字符串未选中,因为它已通过擦除消除
大小写:Foo[String]=>“String”
^
:12:错误:图案类型与预期类型不兼容;
找到:Foo[String]
必需:Foo[Int]
大小写:Foo[String]=>“String”
^

在您的例子中,编译器知道
foo

的确切类型,它被擦除。在您的例子中,编译器可以静态地检查
foo
是否为
foo[Int]
,并且这里的匹配表达式仅对
foo[Int]
foo[\u]
Any
AnyRef
scala.Product
scala.Serializable
)有意义

但是,如果使用基类
Any
隐藏
foo
实际类:

val foo: Any = Foo[Int]("foo")
val res = foo match {
  case _: Foo[String] => "string"
  case _              => "other"
}
println(res) // string
您将收到以下警告:

类型模式Foo[String]中的非变量类型参数字符串为 未选中,因为它是通过擦除消除的


程序将打印“字符串”。

为什么您认为它被删除了?我认为
Foo
List
属于同一个桶中。我想也是这样,但我不能完全肯定。
val foo: Any = Foo[Int]("foo")
val res = foo match {
  case _: Foo[String] => "string"
  case _              => "other"
}
println(res) // string