【问题标题】:Scala - Why does my for loop not return?Scala - 为什么我的 for 循环不返回?
【发布时间】:2018-07-18 10:15:27
【问题描述】:

我正在尝试使用 Scala 执行一些重试逻辑。为了提供 MRE,我将异常抛出对象替换为 Y。运行X.main 时。我希望看到这会打印两条失败消息,然后是一条成功消息,但似乎 return 语句实际上是在充当空操作,并且我看到了 3 条成功消息。

我意识到这不是惯用的 Scala,还有很多其他方法可以做到这一点,但是没有办法从 Scala 中的 for 循环中返回吗?如果不是,那是为什么呢?

object X {
  def main(args : Array[String]) : Unit = {

    val y = new Y()

    for ( i <- 1 to 5 ) {
      try {
        y.doSomething()
        return
      } catch {
        case e : Throwable =>
          if ( i == 5 ) {
            throw e
          }
      }
    }
  }
}

class Y {
  var counter = 0

  def doSomething() : Unit = {
    if ( counter < 2 ) {
      println("Tried to do something, but failed")
      counter += 1
      throw new RuntimeException
    }
    println("Did something")
  }
}

【问题讨论】:

    标签: scala for-loop return


    【解决方案1】:

    return 比您想象的更奇怪,而不仅仅是“非惯用语”。 它实际上抛出异常。您的 catch 子句抓住并吞下了它。这就是为什么它“充当无操作”的原因。

    不要这样做。请。

    但是,如果您坚持,请至少按照评论中的建议执行catch { case NonFatal(e) =&gt; - 这将允许return 引发的异常。

    【讨论】:

    • 另外,使用NonFatal 来避免捕获returns 抛出的ControlThrowable。见scala-lang.org/api/2.12.4/scala/util/control/NonFatal$.html
    • 谢谢!关于您的“不要这样做”的评论-我实际上并没有计划。我更想了解return 在床单下的行为。在发布这个问题之前,我使用尾递归重写了这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2018-10-11
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    相关资源
    最近更新 更多