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, и нет абсолютно никакого способа узнать, какой тип времени компиляции у него был. Вы могли бы, однако, кодировать одну из нескольких вещей:

  1. Для каждого списка в a выведите подмножество Ints.

  2. Получите списки, которые содержат только Ints.

  3. То же, что № 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()

См. Тип безопасного литья в обзоре бесформенных элементов.

Другие вопросы по тегам