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

kem*_*iya 6 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")
}
Run Code Online (Sandbox Code Playgroud)

我收到一些警告,例如<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")
}
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*nov 5

匹配的问题: 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")
}
Run Code Online (Sandbox Code Playgroud)

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

但类型擦除仍然发生。这意味着您实际上可以获得Map[String, Any]除 a in之外的其他内容e,但只能通过以某种方式向编译器撒谎或忽略其他警告。在这种情况下,匹配仍然成功。例如

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