scala中的"return"和"try-catch-finally"块评估

xie*_*fei 14 scala

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

def x = try{
  true
} finally false
Run Code Online (Sandbox Code Playgroud)

调用x得到 true

def y:Boolean = try{
  return true
} finally {
  return false
}
Run Code Online (Sandbox Code Playgroud)

调用y得到 false

return版本的行为与Java相同.

我个人从不在scala中使用'return'.但是知道scala如何评估try-catch-finally块的值是很好的.谢谢.

Thi*_*ilo 13

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

如果Scala finally块具有隐式返回,那么总是会破坏预期的返回值.所以这没有意义.

但是,如果您明确地以这种方式编写它,我想它无法帮助您.

  • Thilo是对的.将`return`语句放在`finally`块中应该被认为是一个错误,实际上是不允许的.`finally`是清理东西,无论方法体成功还是抛出异常.这不是决定回报价值的地方!因此,`finally`子句的主体被用来评估`Unit`.在你的第一个例子中,`false`被隐式转换为`Unit`. (2认同)

Sub*_*oid 9

根据Scala语言规范:

try表达式try {b}最后e计算块b.如果b的评估没有引起异常,则评估表达式e.如果在评估e期间抛出异常,则对抛出的异常中止try表达式的评估.如果在评估e期间没有抛出异常,则返回b的结果作为try表达式的结果.

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

def z : Boolean = {
  val foo = try { true } finally { return false }
  true
}
Run Code Online (Sandbox Code Playgroud)

调用z返回false.

  • `return`总是打破流量控制.在这种情况下,它只会变得特别奇怪. (11认同)
  • 是的,从finally块返回打破流量控制.应该禁止. (3认同)