作为 Swift 5 最值得期待的新功能之一,Result 类型该如何使用?

栏目: Swift · 发布时间: 5年前

内容简介:Swift 5Result 类型强制用一种安全的方法来处理函数调用返回的错误,而不需要抛出异常。尽管它通过异常,提供了一种自动化的机制来进行错误的传递和处理,但是 Result 类型提供了一种手动机制,它有更强大的类型保障,并更适合于异步错误处理。与 OptionSwift 5 中的 Result 类型作为枚举

Swift 5 最值得期待 的新功能之一 Result 终于进入到了该语言中来了。Result 类型强制 程序员 在能够访问到实际值之前显式地处理失败和成功的情况。让我们来看看它是怎么实现的,你可以怎么使用它,为什么我们需要它。

Result 类型强制用一种安全的方法来处理函数调用返回的错误,而不需要抛出异常。尽管它通过异常,提供了一种自动化的机制来进行错误的传递和处理,但是 Result 类型提供了一种手动机制,它有更强大的类型保障,并更适合于异步错误处理。与 Option 类型 相似,Result 类型是一个 monad

Swift 5 中的 Result 类型作为枚举 实现 有两种情况:.success 和.failure。

复制代码

publicenumResult<Success,Failure:Error> {
///A success, storing a`Success`value.
casesuccess(Success)

///A failure, storing a`Failure`value.
casefailure(Failure)
...
}

你可以定义一个简单的函数,返回 Result 并按如下方式处理它的结果:

复制代码

enumAnErrorType:Error{
casefailureReason1
casefailureReason2
}

funcfailableFunction()->Result<Int,AnErrorType> {

...
if(errorCondition1) {
return.failure(.failureReason1)
}
...
return.success(1)
}

funccallFailableFunction(){

...
letresult = failableFunction()
switchresult {
case.success(letintegerResult):
...
case.failure(leterror):
switcherror {
case.failureReason1:
...
case.failureReason2:
...
}
}
...
}

此外,为了更便于和现有的函数集成,Result 类型支持特定的初始化程序,它可以接受可能扔出的闭包:

复制代码

letresult = Result {tryString(contentsOfFile:configuration)}

作为 monad,Result 实现已知的 map() 和 flatMap() 方法(以及理论上相同的 mapError() 和 flatMapError()):

  • map() (mapError()) 通过闭包实现自动值转换,但这仅仅在成功(或失败)的情况下发生,否则 Result 就保持不变。
  • 当你想要使用闭包来转换你的值(错误)的时候,flatMap() (flatMapError()) 很有用,因为闭包会返回一个 Result 来处理转换失败的情况。在这种情况下,map() (mapError()) 会返回一个 <Result<Result<…>>。但有了 flatMap() (flatMapError()),你就能得到简单的 Result。

Result 类型代表了对自 Swift 2 开始 Swift 中简单的错误处理机制的 do、try、catch、throw 语法的改进,有多个原因。

首先,使用 Result 类型处理异步失败变得更加自然。在 Swift 中典型的处理异步函数调用的模式是使用回调,如下例所示:

复制代码

asyncOperationCall(){ (value, error)in

guard error != nilelse{ self.handleError(error!)}
self.handleValue(value)
}

你可能很简单就能发现,使用回调会破坏 Swift 的异常目的 ,即自动传递和处理错误。相反,有了异步回调,错误必须就地处理,因为当回调抛出异常的时候,错误再自动传递到调用堆栈就已经太迟了。相反,当其他人尝试使用返回值的时候,Result 可能会存储,并在稍后再进行处理。这种属性称为有 延迟错误处理 ,不专属于异步代码,会大大简化 Swift 的语法,如下面的例子所示:

复制代码

do{
handleOne(tryString(contentsOfFile:oneFile))
} catch {
handleOneError(error)
}

do{
handleTwo(tryString(contentsOfFile:twoFile))
} catch {
handleTwoError(error)
}

do{
handleThree(tryString(contentsOfFile:threeFile))
} catch {
handleThreeError(error)
}

上面的代码在 Swift 5 中转换为更容易阅读的代码片段,如下所示:

复制代码

letone = Result {tryString(contentsOfFile:oneFile)}
lettwo = Result {tryString(contentsOfFile:twoFile)}
letthree = Result {tryString(contentsOfFile:threeFile)}

handleOne(one)
handleTwo(two)
handleThree(three)

Result 的另外一个优势是我们知道我们要么得到错误,要么得到值。当使用回调的时候,我们可能得到四种类型的组合:没有错误的好的值、有错误且没有值、有值但有错误、没有值且没有错误。

最后,使用 Result 类型可以限制可能返回的错误类型。在上面提供的第一个例子里,这个属性帮助我们能够根据错误处理路径完全枚举可能的错误原因,比如说.failureReason1 和.failureReason2。相反,Swift 的函数抛出的错误并没有指定类型,因此当处理 catch 块中的错误条件时,你只能知道错误符合 Error 协议。

Swift 5 计划在 2019 年初发布 ,目标是 给语言带来 ABI 稳定性

查看英文原文: Previewing Swift 5 Result Type


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人人都是产品经理——写给产品新人

人人都是产品经理——写给产品新人

苏杰 / 电子工业出版社 / 2017-6 / 66.60

《人人都是产品经理——写给产品新人》为经典畅销书《人人都是产品经理》的内容升级版本,和《人人都是产品经理2.0——写给泛产品经理》相当于上下册的关系。对于大量成长起来的优秀互联网产品经理、众多想投身产品工作的其他岗位从业者,以及更多有志从事这一职业的学生而言,这《人人都是产品经理——写给产品新人》曾是他们记忆深刻的启蒙读物、思想基石和行动手册。作者以分享经历与体会为出发点,以“朋友间聊聊如何做产品......一起来看看 《人人都是产品经理——写给产品新人》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具