好吧,这场辩论每隔几个月就会在开发者 subreddits 和论坛上出现一次
你应该使用返回码还是异常来进行错误处理?
老实说,这里没有百分之百正确的答案!两者都有优缺点,并且根据语言或上下文,其中一种可能比另一种更合理。让我们来看看……
1. 返回码 —— 被称为“老派方式” ——
返回码(例如成功用 0,失败用 -1 等)是最初的方法。你主要在 C 和 C++ 中随处可见它们。
它们非常明确,函数直接返回操作的结果。
➕ 使用返回码的优点
- 你总是知道什么时候出了问题
- 没有隐藏的控制流——所见即所得
- 通常速度更快(没有栈展开,没有异常开销)
- 易于在系统编程、嵌入式开发或性能关键型代码中使用
➖ 使用返回码的缺点
- 很容易忘记检查返回值(然后,砰,静默失败 😬)
- 让代码变得冗杂……每个函数调用后面都跟着
if (result != SUCCESS)很烦人 - 除非手动构建,否则没有堆栈跟踪或上下文信息
例如:
try
{
await SendEmailAsync();
}
catch (Exception e)
{
Log.Exception(e.ToString());
return -1;
}
看起来不错……直到你在某个地方忘记了其中一个 if 条件。
2. 异常 —— 花哨 & 现代的方式 ——
异常出现得较晚,主要是在 Java、C# 和 Python 这类高级语言中。 其思想是你抛出一个错误,并在其他地方处理它。
➕ 抛出异常的优点
- 代码更清晰……你可以专注于正常流程,单独处理错误
- 可以携带详细信息(堆栈跟踪、消息、内部异常……)
- 更容易处理复杂的错误传播
➖ 抛出异常的缺点
- 隐藏的控制流——你并不总能看出什么可能会抛出异常
- 性能损耗(尤其是在紧密循环或低级系统中)
- 在某些代码库中被过度使用(“所有东西都抛出所有异常”)
例如:
try
{
await SendEmailAsync();
}
catch (Exception e)
{
Log.Exception(e.ToString());
throw e;
}
这种方式更清晰,但如果 SendEmailAsync() 在你的调用栈深处并且失败了,除非你正确记录日志,否则可能很难确切知道哪里出了问题。
那么哪个更好呢? ⚖️
这取决于你在构建什么。
- 低级系统、驱动程序、实时应用 👉 返回码。 性能和控制更重要。
- 应用程序级别、业务逻辑或高级 API 👉 异常。 更清晰,也更容易维护。
老实说,有时混合使用两者是有意义的。 例如,你可以在内部使用返回码,在 API 边界处使用异常,以便向用户呈现有意义的错误。
结论
返回码 = 简单、明确,但凌乱。 异常 = 清晰、强大,但可能会咬你一口。 选择适合你的项目和你团队理智水平的方式 😅。
译自:https://abp.io/community/articles/return-code-vs-exceptions-which-one-is-better-1rwcu9yi

Comments