异常机制的最佳实现是什么?
大多数程序语言都有某种异常处理。一些语言具有返回码,其他语言具有try / catch或者抢救/重试等,每种语言在大型团队开发工作中在可读性,健壮性和实际有效性方面都有自己的特色。哪一个最好,为什么?
解决方案
回答
try / catch / finally出色地完成了这项工作。
它允许程序员优雅地处理特定条件和一般故障。
所有人都说完了,我敢保证每个人都一样。
回答
我必须采用"尝试/捕获"概念。我觉得就可读性而言,这为代码维护者提供了最多的帮助。只要正确键入异常并且关联的消息包含足够详细的数据,查找函数调用链就应该很简单(我个人不喜欢包含堆栈跟踪,但是我知道很多人这样做,这甚至可以做到这一点)返回代码实现需要在每个程序的基础上有一个外部代码定义表。从个人经验来看,既难以维护又难以参考。
回答
我会说这取决于我们问题的性质。不同的问题域可能需要几乎任意的错误消息,而其他琐碎的任务仅在错误时可以返回NULL或者-1.
错误返回码的问题在于我们正在污染/掩盖错误,因为可以忽略该错误(有时在API客户端不知道它们应该检查错误代码的情况下)。它从手边的方法提供了(合理的)有效输出。
想象一下,我们有一个API,在其中我们需要一些地图的索引键,将其存储在列表中,然后继续运行。然后,API稍后会发送回调,然后该方法可能会使用此示例中的键(错误代码)使用-1遍历表。 BOOM,当我们在某些数组中将索引索引为-1时,应用程序崩溃,并且很难确定这类问题。这仍然是一个简单的示例,但是它说明了错误代码的问题。
另一方面,错误代码比抛出异常更快,并且如果适合返回此类错误代码,则可能需要将它们用于频繁访问的方法调用。我想说,尝试将这些错误代码封装在私有程序集中将是完全可以的,因为我们没有将这些错误代码公开给API的客户端。永远记住要严格地记录这些方法,因为这类应用程序核能会在应用程序中徘徊很长时间,因为它们是在应用程序关闭之前就被触发的。
就个人而言,在某种程度上,我更喜欢将两者混合使用。当程序运行到意想不到的状态并且需要通知某些事情已经超出计划时,我只使用例外。我不喜欢在代码中编写try / catch块,但这完全取决于个人喜好。
回答
最适合什么?语言设计始终要权衡取舍。返回码的优点是,除了常规的函数调用外,它们不需要任何运行时支持。缺点是1)我们总是必须检查它们2)返回类型必须具有一个失败值,该值不是函数调用的有效结果。
自动异常处理的优点是代码中的错误情况不会消失。
各种语言(以及Lisp的条件系统,E的弹出器等)中的异常处理语义之间的差异主要表现在应继续执行程序时如何处理堆栈展开。
总而言之:当我们需要编写可读性强的软件时,特别是在大型团队中,自动异常处理非常有价值。让计算机为我们跟踪错误情况将使我们在阅读代码时无需再多考虑,并且消除了出错的机会。我唯一使用返回代码表示错误的时间是,如果我正在使用一种没有异常处理的语言来实现这种语言。
回答
有关异常处理的不同寻常的观点,请参见Haskell的Control.Exception
monad。