为什么与tuple类型的提取器一起使用的for-comprehension导致`filter`上的编译警告?

时间:2015-10-21 10:04:34

标签: scala for-comprehension extractor

给出以下代码片段:

import scala.util.Try

def foo(x:Int) : (Int, String) = {
  (x+1, x.toString)
}

def main(args: Array[String]) : Unit = {
  val r1: Try[(Int, String)] = for {
    v <- Try { foo(3) }
  } yield v

  val r2: Try[(Int, String)] = for {
    (i, s)  <- Try { foo(3) } // compile warning refers to this line
  } yield (i, s)
}

1。为什么编译上面的代码会抛出以下警告?

`withFilter' method does not yet exist on scala.util.Try[(Int, String)], using `filter' method instead
[warn]       (i, s)  <- Try { foo(3) }
[warn]                      ^
[warn] one warning found

2。为什么在提取元组时根本使用withFilter

更新

  • Scala 2.10.5
  • 发出警告
  • Scala 2.11.7
  • 发出警告

独立于警告信息,我非常想知道是否使用withFilter? (见问题2)

1 个答案:

答案 0 :(得分:4)

似乎Try.withFilter仅在2.11中添加(请参阅Try 2.10.6Try 2.11.0

使用

withFilter代替filter进行理解,因为它很懒,您可以在this question中阅读更全面的比较。

你理解的第二个类似于:

Try(foo(3)).withFilter {
  case (i, s) => true
  case _      => false
} map(identity)

因为在Scala 2.10.5中Try.withFilter不存在,所以它会回退到使用filter(创建新的Try)。

修改:为什么您需要withFilter并不是那么明显,因为您实际上并未使用(i, s)模式匹配进行过滤。

如果您在下面编写了for comprehension,则更清楚的是,您可以在为了理解的左侧添加模式匹配时进行过滤。

for {
  (i, "3") <- Try(foo(3))
} yield i

类似于:

Try(foo(3)) withFilter {
  case (i, "3") => true
  case _        => false
} map { case (i, "3") => i }

正如您所看到的,withFilter不仅用于添加if保护,还用于模式匹配时。