php - 为什么要使用“finally”关键字?




error-handling try-catch (2)

简答

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

这有点在这里解释: https://www.php.net/manual/en/language.exceptions.phphttps://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

所以很多时候,人们把最后一块放在那里以确保一条重要的线路运行,即使它们忽略了catch块中的某些东西。 这就是我一直看到它的用法。

希望这有助于:)

这个问题在这里已有答案:

我理解“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 情况?

例如,如果我在这里遗漏了一些东西,那么 finally 语句是必要的并且不同于在try / catch语句之后放置代码会有所帮助。


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

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

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

  • 如果 try {} 块中的代码抛出一个未由任何 catch {} 块处理的异常,或者根本没有任何异常,则它将运行。 ( finally {} 块在异常传播给调用者之前运行。)

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

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

(有一个边缘情况, finally {} 块不会运行,如果整个进程被销毁,例如被杀死,或者通过调用 exit()die() 。)





try-catch