在程序中明确提出异常有哪些应用和优势。例如,如果我们在这里特别考虑Ada语言提供了一个在程序中引发异常的接口。例如:
List
但是我们需要明确提出异常的优势和应用领域是什么?
例如,在接受其中一个参数为string:
的过程中raise <Exception>;
如果我在上面的函数中引发异常并且在传递的字符串长度限制超过容许限制时处理它,是否有任何优势或良好实践?或者一个简单的If-else处理程序逻辑应该做生意吗?
答案 0 :(得分:2)
显式引发异常以控制向子程序的用户报告哪个异常。 - 或者在某些情况下只是为了控制与引发的异常相关联的消息。
在非常特殊的情况下,您也可以将异常作为程序流控制引发。
答案 1 :(得分:2)
为了捆绑各个方面,我会给出2美分的答案。让我们从一般性问题开始
但是我们需要明确提出异常的优势和应用领域是什么?
提出异常有几个典型的原因。其中大多数都不是Ada特定的。
首先,可能存在使用或不使用例外的一般设计决策。一些一般标准:
一旦做出了使用异常的一般决定,就会出现问题,在不适合的情况下,在代码中提出它们是合适的。我在评论中提到了一个通用标准。我想到了什么:
raise
该自定义异常。现在来看你的具体代码问题:
如果我在上面的函数中引发异常并且在传递的字符串长度限制超过容许限制时处理它,是否有任何优势或良好实践?或者一个简单的If-else处理程序逻辑应该做生意吗?
我并不特别喜欢(虽然我觉得不太可怕),因为我上面的一般论点(“如果你能在本地处理它,不要提高”)会表明一个简单的if / else更清晰。 1 例如,如果函数很长,异常处理程序将远离错误位置,因此可能想知道异常可能发生在哪里(找到一个raise
位置是不能保证一个人找到了所有这些,所以审稿人必须仔细检查整个功能!)。
但这取决于具体情况。如果在多个地方发生错误,则引发异常可能会很优雅。例如,如果几个字符串可能太短,通过异常处理程序进行集中式错误处理可能会很好,而不是在函数体中散布if / then / elses(嵌套??)。情况非常普遍,a legitimate case can be made for using goto
constructs语言没有例外。一个例外显然是优越的。
1 但在所有现实中,你如何处理那个错误?你有一个有保障的伐木设施吗?你有什么回报?调用者是否知道结果可能无效?也许你应该扔掉 not catch。
答案 2 :(得分:2)
给定示例有两个问题:
Constraint_Error
是一个非常糟糕的例外,用于检测字符串长度错误。标准异常Program_Error
,Constraint_Error
,Storage_Error
应该保留用于编程错误条件,并且在大多数情况下应该在可执行文件损坏之前将其删除,并提供足够的调试信息(至少是一个堆栈追溯)让你找到错误并保证它永远不会再发生。 非常令人满意的是让Constraint_Error
尴尬地指向你的错误,而不是后来发生的任何未定义的行为......(学习如何开启它是有用的堆栈回溯,默认情况下通常不会启用。)
相反,您可能希望定义自己的String_Size_Error
异常,提出并处理它。然后,未正确的代码中提升Constraint_Error
的任何其他内容都将被正确调试,而不是静默生成错误的Chars_Ptr
。
对于提高异常的有效用例,请考虑使用SPICE(或用于气体流动的CFD模拟器等)的电路仿真器。由于矩阵计算中出现的数值问题,这些工具即使在正常工作时也容易出现故障。 (两个项取消,产生零+/-舍入误差,这导致不可靠的大数或稍后被零除)。它通常是迭代近似,其中误差应该在每个步骤中减小,直到它具有可接受的低值。但如果发生故障,错误术语将开始增长......
通常,模拟逐步进行,其中每个步骤都是足够小的时间步长,可能是1 us或1 ns。主循环请求一个步骤,并且该请求被传递给模拟中代表电路中的组件或CFD网格中的三角形的数千个代理。
这些代理中的任何一个都可能无法计算解决方案,处理失败的最简单方法是引发异常,可能是Convergence_Error
。可能存在数千个可能引发异常的点。
测试成千上万的返回代码会很快变得难看。但是除了例外,主循环只需要一个处理程序,它需要采取一些纠正措施,例如减少模拟步长并再次运行步骤。
在浏览器中清理用户文本输入可能是另一个很好的用例,更接近示例代码。
关于异常的运行时成本的一个词:Gnat编译器及其RTS支持&#34;零成本异常&#34; (ZCX)模型 - 至少对某些目标而言。在提出异常时会有更大的惩罚,作为在正常情况下消除罚款的权衡。如果惩罚对您很重要,请参阅文档以了解您的情况是否值得。或者
答案 3 :(得分:1)
例外情况应该与他们的名字保持一致,即代表特殊情况。