【问题标题】:Scala closure behavior during exception handling异常处理期间的 Scala 闭包行为
【发布时间】:2017-04-24 15:54:54
【问题描述】:

我正在阅读与 Scala 中的异常处理相关的文章,并在 this 博客上看到了这段代码 sn-p。

def containsEven(nums: String*): Boolean = {
    try {
      for (i <- nums) {
        if (i.toInt % 2 == 0)
          return true
      }
    } catch { case e => () }
    false
  }

无论输入如何,此代码始终返回 false 作为输出。这是在博客上给出的解释。

从上面的实现中,我们期望 containsEven("1", "3") 应该返回 false 并且 containsEven("2", "3") 应该返回 真的。不幸的是,情况并非如此,无论输入如何 我们的方法总是返回 false。这是因为在 catch 块中,我们 使用了一个通过表达式 case e => 捕获 Throwable 的模式 ...而不是更长但更正确的模式案例 e: NumberFormatException => ... 只捕获 NumberFormatException。 要了解为什么这是导致错误的原因,我们需要了解 Scala 如何实现闭包的非本地返回。

还有更多相关的解释

非本地返回

作为一个天真的 Scala 程序员,我无法理解。

那么有人可以用更简单的语言帮助我理解在这种情况下闭包有什么问题吗?

【问题讨论】:

    标签: scala exception closures


    【解决方案1】:

    return 语句实际上会抛出,这意味着下一行执行可能不是本地的。因为case e 是不分青红皂白的,所以它会捕获所有可投掷物。现在trycatch 都已完成,因此继续执行下一行false,并以该值退出def

    把它放在适当的位置,看看你通过各种输入得到什么。

    catch { case e => println(s"caught:$e");() }
    

    这会给你带来完全不同的结果。

    catch { case e: NumberFormatException => println(s"caught:$e");() }
    

    【讨论】:

    • 我同意您建议的更改。我保留了catch { case e =&gt; 以了解它为什么会这样。
    猜你喜欢
    • 2017-09-30
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 2017-12-20
    • 2014-06-15
    • 2020-02-07
    相关资源
    最近更新 更多