学习Swift -- 错误处理
错误处理
错误处理是响应错误以及从错误中返回的过程。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中的错误处理和其他语言中的异常处理很像,使用了try、catch和throw关键字。但是和这些语言——包括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 -- 错误处理的更多相关文章
- ios -- 教你如何轻松学习Swift语法(三) 完结篇
前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 一.自动引用计数 1.自动引用计数工作机制 1.1 swift和o ...
- ios -- 教你如何轻松学习Swift语法(二)
前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 一.可选类型(重点内容) 1.什么是可选类型? 1.1在OC开 ...
- ios -- 教你如何轻松学习Swift语法(一)
目前随着公司开发模式的变更,swift也显得越发重要,相对来说,swift语言更加简洁,严谨.但对于我来说,感觉swift细节的处理很繁琐,可能是还没适应的缘故吧.基本每写一句代码,都要对变量的数据类 ...
- Swift 错误记录
最近几天开始学习Swift,作为一个从 OC 转到 Swift 的程序员,我一直以为很简单.但是现在学习一个星期之后,发现问题还是蛮多的! 最大的问题就是 太特么 不习惯了!!!!!!!!!! 好吧, ...
- 一步一步学习Swift之(一):关于swift与开发环境配置
一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Sw ...
- 開始学习swift开发
近期要開始学习swift开发了,接下来的日子,会记录学习swift的历程.
- 学习swift语言的快速入门教程推荐
随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...
- CAN总线学习总结——错误帧和错误状态
CAN总线学习总结——错误帧和错误状态 标签: 数据 / 错误帧 / 错误状态 / CAN总线 / 总线协议 253 一.五种CAN总线可能发生的错误 1.CRC错误: 接收节点计算出的CRC校验值, ...
- 一步一步学习Swift之(二):好玩的工具playground与swfit基础语法
playground好于在于能一边写代码一边看到输出的常量变量的值.不需要运行模拟器. 我们来试一下该工具的用法. 打开xcode6开发工具,选择Get started with a playgrou ...
随机推荐
- 系统的启动模式(启动级别)的改动---使用upstart启动机制的
/********************************************************************* * Author : Samson * Date ...
- Java高级--Java线程运行栈信息的获取 getStackTrace()
我们在Java程序中使用日志功能(JDK Log或者Log4J)的时候,会发现Log系统会自动帮我们打印出丰富的信息,格式一般如下:为了免去解析StackTrace字符串的麻烦,JDK1.4引入了一个 ...
- 使用tuple返回多个值
17.4编写并测试findbook函数 #include<iostream> #include<vector> #include<string> #include& ...
- linux解压缩命令
1.tar -cvf /data/sc2.tar /data (只打包,不压缩) 把/data下的文件打包成 sc.tar 上面两个都是绝对路径噢 tar -zcvf /data/sc2.tar.g ...
- 如何设计一个更好的C++ ORM
2016/11/26 "用C++的方式读写数据库,简直太棒了!" 上一篇相关文章:如何设计一个简单的C++ ORM (旧版代码)
- java定义类 对象,引用,指针
java是根据面向对象编程,因此有类和对象的概念,类分为普通类与抽象类. 一.定义类 类由N个 构造器 成员变量 方法组成,可以不定义,也可以根据语法定义N个. [修饰符] class 类名{ 构 ...
- java Map使用Object 做为Key的问题
近期在看dnsjava 源码的时候,不经意间发现一个自己没有想过的问题: HashMap 如何使用key去查找对应的value的,这个问题很难用语言描述的清楚,那就使用代码来进行说明吧! public ...
- jQuery给CheckBox添加事件
<asp:CheckBox ID="ckbTable" runat="server" Checked="false" /> &l ...
- 插件使用总结-jquery.pin.js
小伙伴们,俺昨天用了jquery.pin.js这个插件,发现了一些自以为是的使用问题.特此做个总结哈. 1.获取: 下载地址: http://www.bootcss.com/p/jquery.pin ...
- [DEncrypt] RSACryption--RSA加密/解密字符串 (转载)
点击下载 RSACryption.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.RSACryption RSA 的密钥产生2.RSACryption RSA的加密函数3.RSACrypt ...