我正在修补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匹配"部分,并且查看Try.apply创建的对象类型,如果没有创建对象,它可以工作,并且无法在没有对象的情况下创建它评估要应用的参数。在这种情况下,我认为这个论点在第一时间没有任何意义。
或者,对于案例类的行为,可能存在一些本质上懒惰的东西?或许我只是遗漏了一些明显的东西。
有人会介意为我澄清这个吗?
答案 0 :(得分:1)
您缺少的部分是Try
的参数必须是名称,以便可以捕获该计算引发的异常并将其作为Failure
来实现。否则,在Try
有机会捕获任何会破坏目的的事情之前,将评估该参数。您甚至可以查看Try.apply
的源代码,这非常简单。它立即强迫它的论点:
def apply[T](r: => T): Try[T] =
try Success(r) catch {
case NonFatal(e) => Failure(e)
}