利用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页面,在此我们可以讨论此主题,甚至可以找到更好的解决方案。