错误处理

错误处理是响应错误以及从错误中返回的过程。swift提供第一类错误支持,包括在运行时抛出,捕获,传送和控制可回收错误。

一些函数和方法不能总保证能够执行所有代码或产生有用的输出。可空类型用来表示值可能为空,但是当函数执行失败的事后,可空通常可以用来确定执行失败的原因,因此代码可以正确地响应失败。在Swift中,这叫做抛出函数或者抛出方法。

错误的表示

在Swift中,错误用符合ErrorType协议的值表示。 Swift枚举特别适合把一系列相关的错误组合在一起,同时可以把一些相关的值和错误关联在一起。因此编译器会为实现ErrorType协议的Swift枚举类型自动实现相应合成。

// 模拟自动售卖机的错误情况
enum VendingMachineError: ErrorType {
// 商品不存在时
case InvalidSelection
// 投入的钱不够时
case InsufficientFunds(required: Double)
// 商品卖完了
case OutOfStock
}

错误抛出 通过在函数或方法声明的参数后面加上throws关键字,表明这个函数或方法可以抛出错误。如果指定一个返回值,可以把throws关键字放在返回箭头(->)的前面。

func canThrowError() throw -> String

func cannotThrowError() -> String

当调用一个抛出函数的时候,在调用前面加上try。这个关键字表明函数可以抛出错误。

let favoriteSnacks = [
"Alice": "Chips",
"Bob": "Licorice",
"Eve": "Pretzels",
] func buyFavoriteSnack(person: String) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
try vend(itemName: snackName)
}

捕捉和处理错误

使用do-catch语句来就捕获和处理错误

do {
try vend(itemName: "Candy Bar")
// 如果vend会抛出错误的话,会传递到catch中
// 可以在catch里处理发生错误后应做的事情,不会造成运行时错误
} catch VendingMachineError.InvalidSelection {
print("Invalid Selection")
} catch VendingMachineError.InsufficientFunds(let amountRequired) {
print("Insufficient funds. Please insert an additional $\(amountRequired).")
} catch VendingMachineError.OutOfStock {
print("Out of Stock")
}
// Insufficient funds. Please insert an additional $0.25.

注意:Swift中的错误处理和其他语言中的异常处理很像,使用了trycatchthrow关键字。但是和这些语言——包括Objective-C——不同的是,Swift不会展开调用堆栈,那会带来很大的性能损耗。因此,在Swift中throw语句的性能可以做到几乎和return语句一样。

禁止错误传播

在运行时,有几种情况抛出函数事实上是不会抛出错误的。在这几种情况下,你可以用forced-try表达式来调用抛出函数或方法,即使用try!来代替try

通过try!来调用抛出函数或方法禁止了错误传送,并且把调用包装在运行时断言,这样就不会抛出错误。如果错误真的抛出了,会触发运行时错误。

enum CustomError: ErrorType {
case SomeError
} func willOnlyThrowIfTrue(value: Bool) throws {
if value { throw CustomError.SomeError }
} do {
try willOnlyThrowIfTrue(true)
} catch {
print("Error")
} try! willOnlyThrowIfTrue(true) // 运行时错误

收尾操作

使用defer语句来在执行一系列的语句。这样不管有没有错误发生,都可以执行一些必要的收尾操作。包括关闭打开的文件描述符以及释放所有手动分配的内存。

defer语句把执行推迟到退出当前域的时候。defer语句包括defer关键字以及后面要执行的语句。被推迟的语句可能不包含任何将执行流程转移到外部的代码,比如break或者return语句,或者通过抛出一个错误。被推迟的操作的执行的顺序和他们定义的顺序相反,也就是说,在第一个defer语句中的代码在第二个defer语句中的代码之后执行。

func processFile(filename: String) throws {
if exists(filename) {
let file = open(filename)
defer {
close(file)
}
while let line = try file.readline() {
// 写文件
}
// defer中的close(file) 会在最后调用。不管有没有抛出错误
}
}

学习Swift -- 错误处理的更多相关文章

  1. ios -- 教你如何轻松学习Swift语法(三) 完结篇

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.自动引用计数   1.自动引用计数工作机制      1.1 swift和o ...

  2. ios -- 教你如何轻松学习Swift语法(二)

    前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦.      一.可选类型(重点内容)   1.什么是可选类型?        1.1在OC开 ...

  3. ios -- 教你如何轻松学习Swift语法(一)

    目前随着公司开发模式的变更,swift也显得越发重要,相对来说,swift语言更加简洁,严谨.但对于我来说,感觉swift细节的处理很繁琐,可能是还没适应的缘故吧.基本每写一句代码,都要对变量的数据类 ...

  4. Swift 错误记录

    最近几天开始学习Swift,作为一个从 OC 转到 Swift 的程序员,我一直以为很简单.但是现在学习一个星期之后,发现问题还是蛮多的! 最大的问题就是 太特么 不习惯了!!!!!!!!!! 好吧, ...

  5. 一步一步学习Swift之(一):关于swift与开发环境配置

    一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Sw ...

  6. 開始学习swift开发

    近期要開始学习swift开发了,接下来的日子,会记录学习swift的历程.

  7. 学习swift语言的快速入门教程推荐

    随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...

  8. CAN总线学习总结——错误帧和错误状态

    CAN总线学习总结——错误帧和错误状态 标签: 数据 / 错误帧 / 错误状态 / CAN总线 / 总线协议 253 一.五种CAN总线可能发生的错误 1.CRC错误: 接收节点计算出的CRC校验值, ...

  9. 一步一步学习Swift之(二):好玩的工具playground与swfit基础语法

    playground好于在于能一边写代码一边看到输出的常量变量的值.不需要运行模拟器. 我们来试一下该工具的用法. 打开xcode6开发工具,选择Get started with a playgrou ...

随机推荐

  1. yii2

    yii2框架官方说明文档 http://www.yiiframework.com/doc/guide/2.0/zh_cn/caching.page yii2创建您的第一个application应用 h ...

  2. 《Linux内核设计与实现》学习笔记之“Linux进程管理机制”

    一.进程(或者称为“任务”)简介 进程是OS最基本的抽象之一,通常进程包括“可执行程序代码”,“其他资源”(如:打开的文件,挂起的信号,内核内部数据,处理器状态,地址空间,一个或多个执行线程等) 二. ...

  3. android Camera拍照 及 MediaRecorder录像 预览图像差90度

    Camera拍照: 今天做照相机程序,结果写好了发现出问题了,预览的图像差90度.相关源代码如下: Camera.Parameters params = camera.getParameters(); ...

  4. java 集合排序(转)

    Java API针对集合类型排序提供了两种支持:java.util.Collections.sort(java.util.List)java.util.Collections.sort(java.ut ...

  5. TCP 连接的建立和终止

    三路握手 建立一个TCP连接时会发生下述情形. (1)服务器必须准备好接受外来的连接.这通常通过调用socket.bind和listen这3个函数来完成的,我们称之为被动打开. (2)客户通过调用co ...

  6. struts2 ajax 实现方式

    在 struts2 中实现ajax,可以使用struts2-json-plugin扩展,但是返回的json字段必须都是Action中的属性,不可以随意的输出文本. 返回任意的文本有两种方式, 方法一: ...

  7. CentOS Linux修改系统时区

    ln –sf /usr/share/zoneinfo/Hongkong /etc/localtime

  8. Mybatis中实现oracle的批量插入、更新

    oracle 实现在Mybatis中批量插入,下面测试可以使用,在批量插入中不能使用insert 标签,只能使用select标签进行批量插入,否则会提示错误 ### Cause: java.sql.S ...

  9. Js的History对象

    History回顾 window.history表示window对象的历史记录 window.history的简单回顾 历史记录中前进/后退,移动到指定历史记录点 window.history.bac ...

  10. 版本控制SVN与Eclipse4.4.1集成 ( eclipse svn:E175002错误解决 )

    Eclipse版本--Luna Service Release 1(4.4.1) SVN版本-----1.8.X 系统OS-------ubuntu 14.04 LTS 1.通过地址安装 Help-& ...