2

对于以下案例类:

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

scala> val foo = Foo[Int]("foo")
foo: Foo[Int] = Foo(foo)

为什么 Scala 会像我认为的那样让我匹配 on 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"
                       ^
4

2 回答 2

2
  class SuperFoo;
  case class Foo[T](name: String) extends SuperFoo {}
  val foo: SuperFoo = Foo[Int]("foo")
  foo match {
    case _: Foo[String] => "foo"
    case _        => "bar"
  }  //> res0: String = foo + warning

在您的情况下,编译器知道foo.

于 2015-01-13T01:52:00.900 回答
0

它被删除。在您的情况下,编译器可以静态检查fooisFoo[Int]并且这里的匹配表达式仅对Foo[Int],Foo[_]Any( AnyRef, scala.Product, scala.Serializable) 有意义。

但是,如果您foo使用例如基类隐藏真实类Any

val foo: Any = Foo[Int]("foo")
val res = foo match {
  case _: Foo[String] => "string"
  case _              => "other"
}
println(res) // string

你会收到警告:

类型模式 Foo[String] 中的非变量类型参数 String 未选中,因为它已被擦除消除

程序将打印“字符串”。

于 2015-01-13T07:19:33.533 回答