筛选器的Scala集合类型

筛选器的Scala集合类型,scala,types,scala-2.8,scala-collections,Scala,Types,Scala 2.8,Scala Collections,假设您有一个列表(1,“1”),它是键入的List[Any],这当然是正确的,也是预期的。现在如果我像这样映射列表 scala> List(1, "1") map { | case x: Int => x | case y: String => y.toInt | } 结果类型是List[Int],这也是预期的。我的问题是,是否存在过滤器的等效映射,因为下面的示例将生成一个列表[任何]。这可能吗?我假设这可以在编译时解决,而不可能在运行时

假设您有一个列表(1,“1”),它是键入的List[Any],这当然是正确的,也是预期的。现在如果我像这样映射列表

scala> List(1, "1") map {
     |   case x: Int => x
     |   case y: String => y.toInt
     | }
结果类型是List[Int],这也是预期的。我的问题是,是否存在过滤器的等效映射,因为下面的示例将生成一个列表[任何]。这可能吗?我假设这可以在编译时解决,而不可能在运行时解决

scala> List(1, "1") filter {
     |   case x: Int => true
     |   case _ => false
     | }
Scala 2.9:

scala> List(1, "1") collect {
     |   case x: Int => x
     | }
res0: List[Int] = List(1)

关于您修改过的问题,如果您只是在包含partialFunction的情况下使用了一个保护,您将得到以下过滤:

scala> val l1 = List(1, 2, "three", 4, 5, true, 6)
l1: List[Any] = List(1, 2, three, 4, 5, true, 6)

scala> l1.partialMap { case i: Int if i % 2 == 0 => i }
res0: List[Int] = List(2, 4, 6)

如果有人在这个问题上结结巴巴地想知道为什么投票最多的答案对他们不起作用,请注意,
partialMap
方法在Scala 2.8最终发布之前被重命名为
collect
。请尝试以下方法:

scala> List(1, "1") collect {
     |   case x: Int => x
     | }
res0: List[Int] = List(1)

(这应该是对Daniel C.Sobral的精彩回答的评论,但作为一个新用户,我还不允许发表评论。)

为什么只有警卫才能这样做?对不起,这是一个非常愚蠢的评论。但是为什么filter()不生成partialMap这样的结果呢?@Joa
filter
不会更改集合的类型,因为它不会修改集合的元素。filter只接受一个谓词,这使编译器在推断结果类型时没有任何操作。而对于部分函数,它可以使用所有情况的结果类型,并计算这些类型的上界作为部分函数的整体类型。