为非错误目的使用异常

时间:2009-07-21 14:48:14

标签: programming-languages exception-handling

使用异常来管理非错误的案例是一种好习惯吗?

在JavaScript和Python中管理生成器中的StopIteration案例(yield关键字)。

9 个答案:

答案 0 :(得分:11)

我会说,不,自发。例外应该用于例外状态,而不是常规程序流。

答案 1 :(得分:10)

通常不,不。 ASP.NET将此用于Response.Redirect - 实际中止线程,然后捕获异常并重置它。这是非常讨厌的,但它确实让你基本上“退出”请求,而不是每个级别的堆栈都知道它需要立即返回。

尽可能避免。如果你认为你绝对去做,请咨询两位同事,介绍设计并询问他们是否可以更干净地做到这一点。如果你们都没有想到更好的解决方法,那就用大量文档来做。

答案 2 :(得分:8)

这取决于语言。每种语言都有自己的设计和习语。对于大多数语言,例外应该是例外。

在C ++,Java和C#等语言中,将异常用于其他任何事情都是非常糟糕的形式。

在Python中,异常更频繁地用于迭代结束之类的事情。还有更多的模型尝试做你想做的事情并稍后处理例外而不是验证输入(“更容易要求宽恕而不是权限”)。例如,如果要打开文件,可以在Java中检查它是否存在,然后打开它并检查是否有有效的流。在Python中,您可以打开它并使用它。如果失败则处理异常。

来自wikipedia文章:

  

Python样式会在出现错误情况时调用异常。在实际使用文件或资源之前,不是测试对文件或资源的访问,而是通常在Python中继续尝试使用它,如果拒绝访问则捕获异常。

     

即使错误没有问题,例外也可以用作非本地控制转移的更一般方式。例如,用Python编写的Mailman邮件列表软件在决定拒绝邮件或保留邮件以供主持人批准时,使用例外来跳出深层嵌套的邮件处理逻辑。

答案 3 :(得分:3)

正如名称所述,异常仅应用于特殊情况。我不会用它来管理非错误案例。

答案 4 :(得分:2)

没有

例外情况只应用于特殊情况(如名称所示)。这意味着:错误。

  • “呃,我找不到这个文件。” - 例外!
  • “呃,我不能除以0.” - 例外!
  • “呃,我不能没有记忆。” - 例外!
  • “结果是2.5。” - 没有例外!

答案 5 :(得分:2)

这是一个非常值得怀疑的做法。如果您认为这对您的情况最好,请确保对其进行全面记录和评论,以使WTF/m失效。

答案 6 :(得分:2)

在我写的数独求解器中,如果拼图已解决,则会抛出异常。

主搜索功能(私有方法)通过对自身进行递归调用进入搜索树。 正常案例无法解决难题,导致只是正常返回调用者; 例外案例是成功解决难题,在这种情况下,我们“抛出(解决方案)”一直到公共方法中的catch子句。

像这样的东西是Scheme中已知的成语,使用call / cc。我在我的C ++程序中模仿它。

我很高兴听到任何人对此方法的赞成或赞成意见。

答案 7 :(得分:1)

没有

通常,系统旨在快速制作非例外情况,而接受特殊情况则会影响性能。因此,抛出/捕获的许多异常将比传统结构慢。

它还使代码的分析和理解更加困难,大多数代码大部分时间都花在维护上。

答案 8 :(得分:1)

我认为有时候例外对于构建DSL很有用。我知道,这听起来很奇怪,但是由于许多语言没有Ruby所具有的功能(返回关键字是可选的,因为返回了最后一个评估表达式的结果),我们使用尽可能的。

例如,我最近尝试构建一个小的JavaScript测试框架,我希望框架用户能够说出一种方式:

skip();
pending("pending message");
fail("failure message");

而不是:

return skip();
return pending("pending message");
return fail("failure message");

这些函数将是库函数,例如,像SkipTest异常一样抛出异常。唯一推荐使用它们的地方是测试方法。这些测试方法总是在try / catch块中执行,其中处理每种类型的异常,并且根据异常,框架采取适当的步骤。

这是我使用Exceptions进行控制流的示例。

这是一个小例子:

$.it("should offer means to explicitly mark a spec as failed", function() {
    $.fail("this spec must fail");
});