利用Swift的灵活性编写简洁的错误处理

Swift中的错误处理

Swift是一种相对年轻的语言,每个版本都带来新的概念。 例如,Swift 2.0提出了一种全新的错误处理机制(嗯,也许不是那么新,有些语言已经有20多年的相似功能了)。 到目前为止,这是一件很重要的事情,因为我们已经有了非常不错和安全的语言,但是我们仍然需要在方法参数中传递错误。 因此,当苹果公司宣布一种新的方式来做到这一点也就不足为奇了。 他们决定添加do-try-catch块,并说服开发人员,这是处理应用程序错误的正确方法。 让我们看一些将NSData转换为JSON字典的常用代码。 在Swift 1中,我们将这样编写:

现在,我们这样写:

是不是更好? 也许有一点,但是仍然很多代码只能用来检查数据是否成功解析。 其次,想像一下您之前没有看过JSONSerialization类,并且这段代码对您来说是完全不熟悉的。 您能告诉我在这里会发生什么类型的错误吗? 不,您不能,您没有任何信息可以抛出哪种类型的错误函数。 您必须深入研究类实现才能找到它。 最后但并非最不重要的一点,异步代码呢? 处理网络错误时, do-try-catch块是否有帮助? 不。 您需要对其进行包装,修改,然后仍然要完成一对成功/失败的旧回调。

同时在Optional世界

当然,我不是唯一不喜欢Apple引入的机制的人。 许多开发人员试图找到一种更好的错误处理解决方案。 他们中的一些人看着我们漂亮的选装件(嗯,不是每个人都漂亮,但仍然如此),并思考如何使用类似的想法来处理错误。 他们找到了解决方案- Result类型诞生了,每个人都很高兴。

还是他们?

Result类型是一个很棒的概念,它在任何情况下都可以使用,保持强类型并提供有关错误类型的信息。 只有一个缺点…这是Result类型最流行的实现:

让我们尝试编写将Data转换为JSON字典的代码,该代码可能会使用Result类型:

等等…就像以前一样……更加冗长…并且每次处理错误时都需要编写此丑陋的switch语句。 是的,它确实比try-catch具有一些大的优势,但是编写起来很不方便。 ……

梦想…

一个晚上,我想知道Swift中理想的错误处理是什么样子。 几分钟后,我得出结论,我仍然喜欢Result方法,它唯一需要的是更好的语法。 在我看来,最好的解决方案看起来像是if let语法为可选参数,但带有附加error变量:

看起来很棒,不是吗? 不幸的是,我们无法在Swift中使用它。 然而…

…实现(几乎)

当Swift在2014年发布时,苹果强调了他们新语言的灵活性。 考虑到这一点,我决定尝试稍微修改一下我们喜欢的语言。 当然, if let语法是不可触及的并且我们无法对其进行任何处理,但是我们还有许多其他工具,例如闭包,尾随闭包语法或枚举方法。 使用这三个工具,我在Result枚举中添加了几行代码:

现在看起来如何? 让我们找出:

好吧,它看起来比开关和try-catch块好得多,对吗? 最重要的是:我们仍然保留类型安全性和有关返回错误的信息。

结论

我花了一个晚上写这段代码,花了半个小时与同事讨论。 我不知道这是不是一个好的解决方案。 我什至不知道在生产代码中使用它是否足够好。 但是我喜欢这种方法,它是Optional概念的自然扩展,我将在我的项目中尝试一下。

我很好奇您对这种方法的看法。 由于我们的博客上还没有评论(尚未!:P),所以我们建议您访问我们的Facebook页面,在此我们可以讨论此主题,甚至可以找到更好的解决方案。