Swift中不可恢复的错误的处理

本文是一个示例,说明了我们如何研究Swift标准库的功能行为,不仅在库文档上而且还在其源代码上建立了我们的知识。

程序员称之为“错误”的所有事件都可以分为两种类型。

  • 由外部因素(例如网络连接故障)引起的事件。
  • 由程序员的错误引起的事件,例如到达开关操作员的情况,这是不可达的。

第一类事件在常规控制流中处理。 例如,我们通过向用户显示一条消息并设置一个应用程序以等待网络连接恢复来对网络故障做出反应。

我们尝试在代码投入生产之前尽早发现并消除第二种类型的事件。 这里的方法之一是运行一些运行时检查,以可调试状态终止程序执行,并打印一条消息,指出错误在代码中的何处发生。

例如,如果未提供但调用了所需的初始化器,则程序员可以终止执行。 在第一次测试运行期间,将始终注意到并修复该问题。

现在很清楚,对于程序员来说,最重要的选择是如果运行时检查显示错误,那么发行时的程序行为应该是什么样的。

这里的关键要点是assert(_:_:file:line:)assertionFailure(_:file:line:)使得程序失败的影响不那么严重。 例如,iOS应用可能已损坏UI(因为某些重要的运行时检查失败),但不会崩溃。

但是这种情况可能不是您想要的。 您可以选择。

Never用作无条件引发错误,陷阱或无法正常终止的函数的返回类型。 这些功能实际上不会返回,它们永远不会返回。

在这五个终止函数中,只有preconditionFailure(_:file:line)fatalError(_:file:line)返回Never因为只有这两个函数无条件地停止了程序执行,因此永不返回。

这是利用Never键入命令行应用程序的一个很好的示例。 (尽管该示例不使用Swift标准库终止函数,而是使用标准C exit()函数)。

如果printUsagePromptAndExit()返回Void而不是Never ,您将收到一条生成时错误消息:“ ‘守卫’主体不能掉落,请考虑使用’return’或’throw’退出范围 ”。 通过使用“ Never您可以事先声明您永远不会退出范围,因此编译器不会给您生成构建时错误。 否则,您应该在保护代码块的末尾添加return ,这看起来不太好。

  • 如果您确定所有运行时检查仅与Debug配置相关,则使用哪个终止函数都没有关系。
  • 在应用-Ounchecked同时仅使用fatalError(_:file:line)同时允许使用fatalError(_:file:line)指令的程序可以访问。
  • 如果您担心运行时检查可能会在发布中以某种方式失败,请使用assert(_:_:file:line:)assertionFailure(_:file:line:) 。 至少您的应用程序不会崩溃。
  • 使用“ Never使您的代码看起来很整洁。
  • WWDC视频“ Swift的新功能”介绍了SWIFT_OPTIMIZATION_LEVEL构建设置(从11分钟开始)。
  • 在Swift中从不内部工作
  • NSHipster关于Never性质的文章
  • Swift论坛上有关建议弃用-Ounchecked讨论。

最初于 2018年12月19日 发布在我的独立博客 witbit.io 上。