为什么在 List[Any] 上匹配不生成未检查的类型警告?

Why doesn't matching on a List[Any] generate an unchecked type warning?

任何人都知道为什么这些会生成未经检查类型的警告...

def anyMap(a: Any): Unit = a match {
  case _: Map[Any, Any] => 
}
//warning: non-variable type argument Any in type pattern scala.collection.immutable.Map[Any,Any] (the underlying of Map[Any,Any]) is unchecked since it is eliminated by erasure

def intList(a: Any): Unit = a match {
  case _: List[Int] =>
}
//warning: non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure

...但这不是吗?

def anyList(a: Any): Unit = a match {
  case _: List[Any] =>
}
//[crickets]

主要是好奇。谢谢

Scala 可以通过检查它是 List 来验证某物的类型是否满足 List[Any]。这是因为 the list type 在它的第一个参数中是协变的,所以即使你给它传递一个 List[Int]List[Double],它们仍然是子类 List[Any],所以所有的编译器必须做的是检查 List,它可以在运行时完成。类型擦除不会影响它执行此操作的能力。

检查某物是否为 List[Int] 需要知道元素的实际类型, 在运行时被 擦除,而 Scala 不能做同样的事情使用 Map[Any, Any] 因为 the map type 在其第一个参数中是不变的。因此,虽然 Map[Any, Int]Map[Any, Any] 的子类,但 Map[Int, Any] 不是。因此,Scala 必须能够检查第一个参数的类型,而这在运行时是做不到的。

可以找到更多关于方差的信息 in the docs