Pergunta

Let

val a = List ("a", 1, 2.34, "b", List(6,7))
a: List[Any] = List(a, 1, 2.34, b, List(6, 7))

and so

a.collect { case s: String => s }
res: List[String] = List(a, b)

However

a.collect { case s: List[Int] => s }

warns that

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))

Hence to ask whether there is a warning-free / correct approach to collect a list of integers.

Many Thanks.

Foi útil?

Solução

On the JVM there isn't enough information at runtime to know whether a List is a List[Int]. Even a List[Any] might just happen to contain only Ints, and there is absolutely no way to tell which compile-time type it had. You could, however, code one of several things:

  1. For each List in a, yield the subset which are Ints.

  2. Yield the Lists in a which contain only Ints.

  3. Same as #1, but eliminate the empty Lists.

For example, #1 could be coded as

a collect { case list:List[_] => list collect { case x:Int => x } }

Outras dicas

As an complement to @AmigoNico's answer, there are utility functions out there that encapsulate all this behind a clean, type-safe function, for example Shapeless's Typeable type class.

Using shapeless 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()

See Type safe cast in the shapeless feature overview.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top