我有
val a = List(1, List(2,3), 4)
Run Code Online (Sandbox Code Playgroud)
我想将任何列表转换为List[Int].我怎样才能做到这一点?
预期的答案是:
List(1,2,3,4)
Run Code Online (Sandbox Code Playgroud)
你不能使用:
a.flatMap({
case i: Int => List(i)
case l: List[Int] => l
})
Run Code Online (Sandbox Code Playgroud)
case l: List[Int]由于类型擦除,该部分不起作用.事实上:
scala> val a = List(1, List("a"), 3)
a: List[Any] = List(1, List(a), 3)
scala> a.flatMap {
| case i: Int => List(i)
| case l: List[Int] => l
| }
<console>:11: warning: non-variable type argument Int in type pattern List[Int] (the underlying of List[Int]) is unchecked since it is eliminated by erasure
case l: List[Int] => l
^
res2: List[Int] = List(1, a, 3)
scala> res2(1) // boom!
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:105)
... 33 elided
Run Code Online (Sandbox Code Playgroud)
在这些情况下,您可能需要考虑使用无形的Typeable类型类进行类型安全转换.例如:
scala> import shapeless.syntax.typeable._
import shapeless.syntax.typeable._
scala> val as = a.flatMap {
| case x: Int => List(x)
| case xs => xs.cast[List[Int]].getOrElse(List())
| }
as: List[Int] = List(1, 2, 3, 4)
scala> val b = List(1, 2, List("a", "b"), 3)
b: List[Any] = List(1, 2, List(a, b), 3)
scala> val bs = b.flatMap {
| case x: Int => List(x)
| case xs => xs.cast[List[Int]].getOrElse(List())
| }
bs: List[Int] = List(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
正如您可以cast[T]通过无形通过方法添加到每个类型的方法一样,如果转换失败,则implicits返回Option[T]其值None,Some如果成功的话.
当然,如果你的第一个列表的内容不是a Int或a,你可以决定失败List[Int].在我的例子中,我决定忽略其他类型,仍然产生一个List[Int].
| 归档时间: |
|
| 查看次数: |
401 次 |
| 最近记录: |