【问题标题】:What triggers Try argument to be evaluated什么触发 Try 参数被评估
【发布时间】:2018-06-16 16:32:14
【问题描述】:

我正在修改 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 创建的对象类型,如果对象没有,则无法工作已创建,并且在不评估要应用的参数的情况下无法创建它。在这种情况下,我首先看不出这个论点有任何意义。

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

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

【问题讨论】:

    标签: scala pass-by-name


    【解决方案1】:

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

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

    【讨论】:

    • 噢!是的,我需要在构造内部发生故障,而不是在准备呼叫时发生。感谢您的耐心!我对内部会发生的事情如此着迷,我完全忽略了这一点。不错。
    猜你喜欢
    • 1970-01-01
    • 2017-09-25
    • 2021-01-16
    • 1970-01-01
    • 2020-04-03
    • 2020-08-15
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多