Scala собирать тип рисунка и тип стирания
Позволять
val a = List ("a", 1, 2.34, "b", List(6,7))
a: List[Any] = List(a, 1, 2.34, b, List(6, 7))
так что
a.collect { case s: String => s }
res: List[String] = List(a, b)
тем не мение
a.collect { case s: List[Int] => s }
предупреждает, что
non-variable type argument Int in type pattern List[Int] is unchecked
since it is eliminated by erasure
a.collect { case s: List[Int] => s }
^
res: List[List[Int]] = List(List(6, 7))
Следовательно, чтобы спросить, существует ли подход без предупреждений / правильно собрать список целых чисел.
Большое спасибо.
2 ответа
На JVM во время выполнения не хватает информации, чтобы узнать, является ли List списком [Int]. Даже List[Any] может содержать только Ints, и нет абсолютно никакого способа узнать, какой тип времени компиляции у него был. Вы могли бы, однако, кодировать одну из нескольких вещей:
Для каждого списка в a выведите подмножество Ints.
Получите списки, которые содержат только Ints.
То же, что № 1, но исключить пустые списки.
Например, #1 может быть закодирован как
a collect { case list:List[_] => list collect { case x:Int => x } }
В качестве дополнения к ответу @AmigoNico существуют служебные функции, которые заключают в себе все это за чистой, безопасной для типов функцией, например, Shapeless's. Typeable
тип класс.
Использование бесформенного 2.0.0-M1:
scala> val a = List ("a", 1, 2.34, "b", List(6,7))
a: List[Any] = List(a, 1, 2.34, b, List(6, 7))
scala> import syntax.typeable._
import syntax.typeable._
scala> a.flatMap(_.cast[List[Int]])
res0: List[List[Int]] = List(List(6, 7))
scala> a.flatMap(_.cast[List[String]])
res1: List[List[String]] = List()
См. Тип безопасного литья в обзоре бесформенных элементов.