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

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

    最佳答案

    好像Try.withFilter仅在 2.11 中添加(参见 Try 2.10.6 Try 2.11.0)
    withFilter用于代替 filter在a for 理解因为比较懒,可以在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 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 守卫时使用,而且在模式匹配时也使用。

    关于scala - 为什么与 tuple 类型的提取器一起使用的 for-comprehension 会导致 `filter` 上的编译警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33256391/

    相关文章:

    scala - 如何通过 scala 中的 Map 动态创建 xml 属性

    azure - 如何设置 Spark Kusto 连接器写入轮询间隔?

    scala - 是否有 Scala 模式用于从一系列独立计算中收集错误消息?

    C++ istream 提取器精度?

    scala - map 上的类型匹配失败

    scala - 使用 foreach 行在数据框中捕获和写入字符串

    sql - 在理解中实现 DISTINCT

    scala - scala 的 for-comprehensions 什么时候懒惰?

    scala - 使用提取器匹配订单

    scala - 自制提取器和案例类提取器的区别