У меня есть следующие утверждения.
val a: Any = Array("1", "2", "3")
a match {
case p: Array[Int] => println("int")
case l: Array[String] => println("string")
}
val b: Any = List(1, 2, 3)
b match {
case l: List[String] => println("string")
case p: List[Int] => println("int")
}
Первый блок о Array компилируется без предупреждений и выводит «строку», а второй о List компилируется с предупреждениями, связанными с стиранием типа, и также выводит «строку».
Я кое-что знаю о стирании типов в JVM. Во время выполнения JVM не может точно знать общий тип контейнера (например, List). Но почему Array может избежать стирания типа во время выполнения и подобрать правильный тип?
Я попытался найти ответ в исходном коде scala. Единственное, что я обнаружил, это то, что Array использует ClassTag, а List - нет.
Хотелось бы узнать, как работает ClassTag. ClassTag - это обходной путь стирания типа? И почему контейнеры, подобные List, не были реализованы с ClassTag, чтобы избежать стирания типа.