0

我正在修补 Try,根据这个:

val files = Stream("a.txt", "b.txt", "c.txt")
files
    .map(s => Try(Source.fromFile(s)))
    .flatMap(t => t match {
      case Failure(x) =>
        Console.err.println(s"Failure: x.getMessage")
        Stream.Empty
      case Success(s) => Stream(s)
    })
  .flatMap(t => t.getLines.toStream)
  .foreach(println)

虽然它可以正常工作,正如我希望/打算的那样,但我有一种不安的感觉,我无法确切地确定“Source.fromFile(s)”部分实际上是如何被评估的。Try.apply 方法的参数被记录为按名称参数,因此显然必须强制对其进行评估。

但是,在我看来,下一个操作将是“t match”部分,这是查看 Try.apply 创建的对象类型,如果尚未创建对象,则无法工作,如果不评估要应用的参数,就无法创建它。在这种情况下,我首先看不出这个论点有任何意义。

或者,也许案例类的行为本质上是惰性的?或者,也许我只是遗漏了一些明显的东西。

有人介意为我澄清一下吗?

4

1 回答 1

1

您缺少的部分是 to 的参数Try必须是按名称命名的,以便可以捕获该计算引发的异常并将其具体化为Failures. 否则,该论点将在Try有机会抓住任何会破坏目的的东西之前进行评估。你甚至可以看一下它的源代码,Try.apply非常简单。它立即强制其论点:

def apply[T](r: => T): Try[T] =
  try Success(r) catch {
    case NonFatal(e) => Failure(e)
  }
于 2018-01-07T14:01:53.750 回答