为什么使用“终于”关键字?简答题更多细节TL;DR

2022-08-31 00:00:29

我理解“finally”关键字在各种语言中的用途,但是,我很难理解为什么你会在口味上有格式偏好之外使用它。

例如,在 PHP 中:

try {
  possibleErrorThrownFunction();
}
catch (CustomException $customException) {
  // handle custom error
}
catch (Exception $exception) {
  // handle the error
}
finally {
  // run this code every single time regardless of error or not
}

此代码正在执行的操作与此代码之间有什么区别?

try {
  possibleErrorThrownFunction();
}
catch (CustomException $customException) {
  // handle custom error
}
catch (Exception $exception) {
  // handle the error
}

// run this code every single time regardless of error or not

由于捕获了错误,最后一行是否总是会运行?在这种情况下,除非您只想维护代码样式的格式,否则没有真正使用的情况?finally

如果我在这里缺少某些内容,那么语句是必要的并且与仅在try/catch语句之后放置代码的情况示例将很有帮助。finally


答案 1

简答题

Finally在允许程序崩溃之前,无论和块内部发生什么情况,块都保证运行。trycatch

这里对此进行了解释:https://www.php.net/manual/en/language.exceptions.php 尽管解释不是特别详细。

更多细节

我脑海中浮现的一个例子是,如果您正在处理输入/输出流或类似的东西,这些流在使用后必须关闭以避免内存泄漏。以您的示例为例:

try {
  memoryUser.startReading(someFileOrSomething);
}
catch (CustomException $customException) {
  // handle custom error
}
catch (Exception $exception) {
  // handle the error
  invisibleBug.whoops(); // i.e. something goes wrong in this block
}

memoryUser.Close(); // because something went wrong in the catch block,
                    // this never runs, which, in this case, causes a memory leak

在这种情况下,将 包装在块中将确保该行在程序的其余部分爆炸之前运行,从而防止内存泄漏,即使在其他灾难性故障中也是如此。memoryUser.Close();finally

TL;DR

所以很多时候,人们把最后的区块放在那里,以确保一条重要的线路运行,即使他们忽略了接球区块中的东西。这就是我一直以来看到它被使用的方式。

希望这有助于:)


答案 2

块的特别之处在于它总是在块的末尾运行。finally {}try {}

  • 如果块中的代码成功完成,它将运行。try {}

  • 如果块中的代码引发被 捕获的异常,它将运行。(运行在 之后。)try {}catch {}finally {}catch {}

  • 如果块中的代码引发任何块都未处理的异常,或者根本没有任何异常,它将运行。(该块在将异常传播到调用方之前运行。try {}catch {}finally {}

  • 如果块中的代码引发异常,并且其中的代码引发一个异常(或重新抛出相同的异常),它将运行。try {}catch {}

  • 如果块或块中的代码使用 .(就像未捕获的异常一样,在函数实际返回之前运行。该块甚至可以使用自身,其返回值将覆盖另一个块尝试返回的值!try {}catch {}returnfinally {}finally {}return

(有一种边缘情况,块不会运行,那就是如果整个过程被破坏,例如被杀死,或者通过调用或.finally {}exit()die()


推荐