模式匹配中的Scala类型擦除Map [String,Any]

时间:2017-10-31 07:49:44

标签: scala pattern-matching type-erasure

我正在使用scala版本2.12.3,当我在控制台代码中测试一些模式匹配时:

val d: Any = Map("1" -> "2", "3" -> 4)
d match {
    case map: Map[String, Any] => println(map)
    case _ => println("should not be here")
}

我收到了一些警告,例如<console>:14: warning: non-variable type argument String in type pattern scala.collection.immutable.Map[String,Any] (the underlying of Map[String,Any]) is unchecked since it is eliminated by erasure

我已经搜索了警告,并且几乎所有答案都被告知scala运行时将在模式匹配时删除类型,并且回答问题似乎是合理的,但是当我使用以下代码时:

val e = Map("1" -> "2", "3" -> 4)
e match {
    case map: Map[String, Any] => println(map)
    case _ => println("should not be here")
}

没有关于类型擦除的警告,那么这两种模式匹配之间有什么区别,请解释何时会发生类型擦除,谢谢!

2 个答案:

答案 0 :(得分:2)

匹配: Map[String, Any]的问题是,它实际上只能检查您在运行时获得Map。例如,

val d: Any = Map(0 -> 0)
d match {
    case map: Map[String, Any] => println(map)
    case _ => println("should not be here")
}

匹配将成功并打印地图。在第二种情况下,e的静态类型已经是Map[String, Any]。所以编译器&#34;知道&#34;您无法获得任何其他类型的Map,并且没有任何问题需要警告。

但是类型擦除仍然发生。这意味着你实际上可以Map[String, Any]中获得e以外的其他内容,但只能以某种方式向编译器说谎或忽略其他警告。在这种情况下,比赛仍然成功。 E.g。

val e = Map(0 -> 0).asInstanceOf[Map[String, Any]]
e match {
    case map: Map[String, Any] => println(map)
    case _ => println("should not be here")
}

答案 1 :(得分:0)

Programming in Scala

中对此进行了解释

第一次收到警告,因为d被强制为Any类型。第二次编译器将e的类型推断为Map [String,Int],这是第一种情况下模式匹配的表达式。编译器在编译时知道类型,所以没有什么可以警告的。