Exception handling 什么可以';不能使用if-else子句,也可以使用异常处理来完成?
if-else子句不能做什么,而异常处理可以做什么 换句话说,我们实际上需要在哪里使用异常处理,而仅仅是if-else不起作用Exception handling 什么可以';不能使用if-else子句,也可以使用异常处理来完成?,exception-handling,Exception Handling,if-else子句不能做什么,而异常处理可以做什么 换句话说,我们实际上需要在哪里使用异常处理,而仅仅是if-else不起作用 异常处理只是显示错误的一种美化方式吗?考虑下面的一个实际示例。您有一个复杂的递归函数,在某些情况下需要退出当前正在进行的所有调用 void complexFunction() { //do stuff, then if( timeToBailOut() ) { // what? how would you get out of all insta
异常处理只是显示错误的一种美化方式吗?考虑下面的一个实际示例。您有一个复杂的递归函数,在某些情况下需要退出当前正在进行的所有调用
void complexFunction()
{
//do stuff, then
if( timeToBailOut() ) {
// what? how would you get out of all instances at once?
}
}
您需要非常仔细地编写那些if
语句,可能会引入一个特殊的返回值,随时检查该值,这将使您的代码变得非常复杂。您可以很容易地实现这种行为,但有例外
if( timeToBailOut() ) {
throw BailOutException();
}
使用异常处理无法完成的事情没有它也做不到,但是,如果没有异常处理,有些情况将是一件痛苦的事情 例如:
a()
调用b()
和b()
调用c()
。必须在a()
中处理的c()
中可能会发生错误。如果没有异常处理,您必须使用b()
和c()
中的哨兵返回值,以及b()
中的额外检查代码来处理它。您可以想象,如果必须将错误从导致错误的原因传递到需要处理错误的原因,那么需要编写多少代码
这是我对a的回答的一个简短版本,之前在这里被问到并被迁移。异常正是它们的名称:破坏当前流程的异常事件或情况 您应该使用异常来表示发生了令人讨厌的异常情况。假设您有一个读取配置文件的类。例外情况可能是:
- 找不到该文件
- 文件存在,但无法读取
您可以用if-else块处理所有这些,但处理异常要简单得多。某些语言(例如C++)在某些情况下不允许返回值。例如,在C++构造函数中没有返回值(甚至
if( timeToBailOut() ) {
throw BailOutException();
}
因此,这不是一个“能”或“不能”的问题。这是一个可读性和性能的问题
在代码的每一行中乱扔错误检查会使人更难遵循非异常(即常见)情况。每个优秀的程序员都知道,代码的主要读者是人类读者
至于性能,if/else比现代异常实现慢。现代实现几乎没有开销,除非实际抛出异常。如果您的异常确实代表“异常”情况,这可能是一个显著的性能差异。当然,您可以编写不使用异常的代码。但是,如果您这样做,您必须确保任何可能发出错误的函数都得到了正确的处理
对我来说,有异常的最大好处是,我可以编写简单的代码,简单地假设所有函数都成功,知道上层将负责报告错误
具体来说,使用以下虚构函数在编辑器中处理文本:
do-stuff:
backward-line 10
x = point
search-for "FOO"
return buffer-substring x point
“后退线”和“搜索”都可能失败。如果我必须自己处理错误,我必须检查它们。此外,我还必须发明一个旁道,向我的调用者报告发生了错误。正如我所说的,这是可以做到的,但这会更加混乱。看,除了手工编码的8086汇编程序所不能做到的例外,你什么也做不了。(图灵完成!)除了手工编码的汇编程序对于一个100K行代码项目来说不是一个很好的工具,除非你是银河系中最好的程序员,如果那样的话。经验表明,在许多情况下,异常处理的习惯用法会产生普通人编写的最健壮的代码。Sharptooth的CTOR示例很好。需要向上传播调用堆栈的错误也是如此编辑:有多少人实际检查了
malloc
每次都没有失败?最好抛出OutOfMemoryException。如果使用转到无法执行的操作,那么可以使用执行哪些操作?if-else
分支仅仅是编写一组有限的goto
s的一种美化方式吗?@pst:没有例外。@sharptooth我想我的观点被忽略了…:)可以说,它可以同样干净地编写,返回(结果、错误)
。当我遇到这种预期的“回退”方法时,我通常会哭。@pst:What wouldearth()
do?@sharptooth它可以被认为是一个具有两个互斥元素的元组,其中一个且只有一个项可以设置(或访问)。可以设置第一个值(通常称为Left),也可以设置第二个值(通常称为Right)。在上面的注释中,我的意思是左边的类型是Result,右边的类型是Error。例如,正常返回将是Left(some\u result)
,而“error”返回将是Right(some\u error)
,两者将统一在或(result,error)
下。通常情况下,模式匹配用于分解为左值或右值。@pst:好的,但是调用方必须检查该值并做出相应的反应,这将是额外的代码。除了例外,它只是顶层的一个捕获。@sharptooth的论点是白露