Exception handling 什么可以';不能使用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

if-else子句不能做什么,而异常处理可以做什么

换句话说,我们实际上需要在哪里使用异常处理,而仅仅是if-else不起作用


异常处理只是显示错误的一种美化方式吗?

考虑下面的一个实际示例。您有一个复杂的递归函数,在某些情况下需要退出当前正在进行的所有调用

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++构造函数中没有返回值(甚至 Value>代码),因此唯一的方法来构造构造函数中的错误是抛出异常。

< P>在最早的C++实现中,异常被编译成等价的I/ER构造,或多或少。它们的速度非常慢,以至于你仍然可以找到一些编程指南,它们以“它们很慢”为理由建议不要出现异常

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 would
earth()
do?@sharptooth它可以被认为是一个具有两个互斥元素的元组,其中一个且只有一个项可以设置(或访问)。可以设置第一个值(通常称为Left),也可以设置第二个值(通常称为Right)。在上面的注释中,我的意思是左边的类型是Result,右边的类型是Error。例如,正常返回将是
Left(some\u result)
,而“error”返回将是
Right(some\u error)
,两者将统一在
或(result,error)
下。通常情况下,模式匹配用于分解为左值或右值。@pst:好的,但是调用方必须检查该值并做出相应的反应,这将是额外的代码。除了例外,它只是顶层的一个捕获。@sharptooth的论点是
白露