GMTC北京站本周日开幕,58个议题全部上线,点击查看 了解详情
写点什么

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

2019 年 1 月 15 日

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

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


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


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


public enum Result<Success, Failure: Error> {  /// A success, storing a `Success` value.  case success(Success)
/// A failure, storing a `Failure` value. case failure(Failure) ...}
复制代码


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


enum AnErrorType: Error {    case failureReason1    case failureReason2}
func failableFunction() -> Result<Int, AnErrorType> {
... if (errorCondition1) { return .failure(.failureReason1) } ... return .success(1)}
func callFailableFunction() {
... let result = failableFunction() switch result { case .success(let integerResult): ... case .failure(let error): switch error { case .failureReason1: ... case .failureReason2: ... } } ...}
复制代码


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


let result = Result { try String(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 != nil else { self.handleError(error!) } self.handleValue(value)}
复制代码


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


do {    handleOne(try String(contentsOfFile: oneFile))} catch {    handleOneError(error)}
do { handleTwo(try String(contentsOfFile: twoFile))} catch { handleTwoError(error)}
do { handleThree(try String(contentsOfFile: threeFile))} catch { handleThreeError(error)}
复制代码


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


let one = Result { try String(contentsOfFile: oneFile) }let two = Result { try String(contentsOfFile: twoFile) }let three = Result { try String(contentsOfFile: threeFile) }
handleOne(one)handleTwo(two)handleThree(three)
复制代码


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


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


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


查看英文原文Previewing Swift 5 Result Type


2019 年 1 月 15 日 12:007456
用户头像

发布了 217 篇内容, 共 53.3 次阅读, 收获喜欢 70 次。

关注

评论

发布
暂无评论
发现更多内容

spring-boot-route(二十一)quartz实现动态定时任务

Java旅途

Java Spring Boot quartz

原来AI也可以如此简单!教你从0到1开发开源知识问答机器人

华为云开发者社区

开源 AI 机器人

让核显大展拳脚:Intel Iris Xe显卡

新闻科技资讯

身为程序员你们经历过大厂面试吗?本文为大家解决大厂必问的MySQL调优问题

Java架构师迁哥

技术实操丨HBase 2.X版本的元数据修复及一种数据迁移方式

华为云开发者社区

数据 数据迁移 原数据

十九、深入Python匿名函数

刘润森

Python

区块链跨境支付系统开发,OTC承兑商支付平台搭建

WX13823153201

区块链跨境支付系统开发

为什么迫切需要一套直接可落地的中台开发框架

高鹏

中台 业务中台 DDD 中台架构 业务架构

被延伸的“五感”:OPPO联合丹拿发起TWS耳机音质革命

脑极体

1分钟带你入门React Context

Leo

前端 React useContext Context 前端进阶训练营

独家!阿里技术人限产的MySQL高级笔记及面试宝典,简直开挂

996小迁

Java MySQL 架构 面试 技术宅

杂谈:一文了解工业4.0

soolaugust

工业互联网 工业4.0

LeetCode题解:98. 验证二叉搜索树,递归中序遍历完成后再判断,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

架构师训练营第 1 期第 5 周作业

业哥

MapReduce简介及过程详解

犟马骝

hadoop mapreduce

视频面试跟传统面试的区别及优点

anyRTC开发者

ios 音视频 WebRTC RTC 安卓

Storage API简介和存储限制与逐出策略

程序那些事

浏览器 web tech web storage storage api 前端存储

vivo 基于原生 RabbitMQ 的高可用架构实践

vivo互联网技术

高可用 RabbitMQ 中间件

WebSocket硬核入门:200行代码,教你徒手撸一个WebSocket服务器

JackJiang

html5 网络编程 websocket 即时通讯

Java程序员想要进阶,想了解Java服务器的深层高阶知识,Netty绝对是一个必须要过的门槛。

Java架构之路

Java 程序员 架构 编程语言 随笔杂谈

最火的HTAP数据库 京东智联云新一代分布式数据库TiDB架构揭秘

京东科技开发者

数据库 #TiDB

1分钟带你入门Redux、React-Redux

Leo

前端 React 前端进阶训练营 Redux React-Redux

【活动预告】2020中国系统架构师大会:即构受邀分享实时音视频服务架构实践

ZEGO即构

架构师 高并发系统设计 技术分享

BIGDATA+AI Meetup 2020第二季·上海站开启报名!

Apache Flink

大数据 AI

【运维思考】运维对象快速扩展,监控如何精准实时的覆盖?

嘉为蓝鲸

PaaS 运维自动化 监控管理平台 监控系统 监控告警

LeetCode题解:98. 验证二叉搜索树,使用栈中序遍历,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

甲方日常 34

句子

工作 随笔杂谈 日常

MySQL-技术专题-MySQL的主从同步

李浩宇/Alex

iOS 性能优化实践:头条抖音如何实现 OOM 崩溃率下降50%+

iOSer

性能优化 OOM ios开发 头条抖音 OOM崩溃

晦涩难懂的CAP,是否完全正确?

架构师修行之路

【高并发】学好并发编程,关键是要理解这三个核心问题

冰河

并发编程 高并发 同步 分工 互斥

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