【问题标题】:"return" and "try-catch-finally" block evaluation in scalascala中的“return”和“try-catch-finally”块评估
【发布时间】:2011-12-09 09:52:16
【问题描述】:

以下两个代码产生不同的结果:

def x = try{
  true
} finally false

调用 x 得到true

def y:Boolean = try{
  return true
} finally {
  return false
}

调用 y 得到 false

return 版本的行为与 Java 相同。

就我个人而言,我从不在 scala 中使用“return”。但是很高兴知道 scala 如何评估 try-catch-finally 块的值。谢谢。

【问题讨论】:

    标签: scala


    【解决方案1】:

    should not 在 finally 块中有一个 return 语句(即使它在技术上是允许的,至少在 Java 中,例如 C# 禁止它)。

    如果 Scala finally 块有一个隐式返回,那总是会破坏预期的返回值。所以这没有任何意义。

    但我想如果你明确地这样写它对你没有帮助。

    【讨论】:

    • 但什么是“隐式回报”?
    • “隐式返回”:可能是用错了词,但我的意思是Scala使用代码块中最后一行的结果作为块的返回值。
    • 蒂洛是对的。将return 语句放在finally 块中应该被视为错误,实际上是不允许的。 Finally 就是不管方法体成功还是抛出异常都要清理东西。这不是决定返回值的地方!因此,finally 子句的主体被用于评估 Unit。在您的第一个示例中,false 隐式转换为 Unit
    • 所以结论是:永远不要在finally 块中使用return,在Scala 中finally 的主体对整个try-catch-finally 表达式的评估没有影响。剪刀使这个答案完整。
    【解决方案2】:

    根据 Scala 语言规范:

    try 表达式 try { b } finally e 计算块 b。如果评估 b 不会引发异常,表达式 e 被计算。如果出现异常 在对 e 求值期间抛出,try 表达式的求值被中止 抛出异常。如果在计算 e 期间没有抛出异常,则 b 的结果作为 try 表达式的结果返回。

    这种行为似乎与该规范相矛盾。我猜想,因为'return' 会导致 函数 立即返回,这会导致覆盖 try 块的标准行为。一个有启发性的例子是:

    def z : Boolean = {
      val foo = try { true } finally { return false }
      true
    }
    

    调用z 返回false

    【讨论】:

    • 是的,从 finally 块返回会破坏流控制。应该禁止。
    • return 总是会中断流控制。在那种情况下,它只会变得特别奇怪。
    • 符合规范。下面的段落说e 的类型应该符合Unit,这意味着e 仅针对其副作用进行评估。当ereturn .. 时,评估规则说控制流离开当前执行的方法,返回给定的参数。
    猜你喜欢
    • 2013-02-19
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多