是什么触发了要评估的 Try 参数

What triggers Try argument to be evaluated

我正在修改 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)

虽然它有效,但与我 hoped/intended 完全一样,我有一种不安的感觉,我无法确定 "Source.fromFile(s)" 部分的实际评估方式。 Try.apply 方法的参数被记录为别名参数,因此显然必须强制对其进行评估。

但是,在我看来,下一个操作将是 "t match" 部分,即查看 Try.apply 创建的对象类型,如果该对象尚未创建,并且在不评估要应用的参数的情况下无法创建它。在这种情况下,我看不出争论放在首位有任何意义。

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

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

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

def apply[T](r: => T): Try[T] =
  try Success(r) catch {
    case NonFatal(e) => Failure(e)
  }