Swift(十八、错误处理)
来源:互联网 发布:苹果手机网络无法连接 编辑:程序博客网 时间:2024/05/22 12:00
1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~
2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。
十八、错误处理
响应错误以及从错误中恢复的过程,在运行时可恢复错误抛出,捕获,传送和操作的高级支持
1、表示并抛出错误
错误遵循ErrorType
协议的值来表示,可用枚举列出错误情景
enum VendingMachineError: ErrorType { case InvalidSelection //选择无效 case InsufficientFunds(coinsNeeded: Int) //金额不足 case OutOfStock //缺货}
使用throw关键字抛出
throw VendingMachineError.OutOfStock
2、处理错误
Swift提供四种方式:
a、把函数抛出的错误传递给调用此函数的代码
b、用do-catch语句处理错误
c、将错误作为可选类型处理
d、断言此错误根本不会发生
2.1、用throwing函数传递错误
在函数参数列表之后,->
之前加上throws
func canThrowsErrors() throws -> String
throwing
函数从其内部抛出错误,并传递到该函数被调用时所在的区域中
struct Item { var price:Int var count:Int}class VendingMachine { var inventory = [ //存货清单 "Candy Bar":Item(price: 12, count: 7), "Chips" :Item(price: 10, count: 4), "Pretzels" :Item(price: 7, count: 11) //椒盐卷饼 ] var coinsDeposited = 0 //存款 func dispenseSnack(snack:String) { //分配零食 print("Dispensing \(snack)") } func vend(itemNamed name:String) throws { guard var item = inventory[name] else { //所需货物要在清单内否则抛出错误 throw VendingMachineError.InvalidSelection } guard item.count > 0 else { //要有存货否则抛出错误 throw VendingMachineError.OutOfStock } guard item.price <= coinsDeposited else { //有足够的金钱购买否则抛出错误 throw VendingMachineError.InsufficientFunds(coinsNeeded: item.price-coinsDeposited) } coinsDeposited -= item.price //存款减去费用 --item.count //存货减一 inventory[name] = item dispenseSnack(name) //调函数说明正在分发物品 }}
根据上面的描述可看出,vend(itemNamed:)
可能抛出错误
使用try
传递,try
后面跟可能发生错误的区域
定义属性
var vend = VendingMachine()
vend.coinsDeposited = 1try vend.vend(itemNamed: "Chips")
Output:
错误处理.VendingMachineError.InsufficientFunds(9)
vend.coinsDeposited = 100
try vend.vend(itemNamed: "Chip")
Output:
错误处理.VendingMachineError.InvalidSelection
其他错误就不一一演示了~验证起来十分简单
2.2、用Do-Catch处理错误
这里的过程相当于将上面的错误提示用一段闭包来处理
var vend = VendingMachine()vend.coinsDeposited = 100
do { try vend.vend(itemNamed: "Chips")} catch VendingMachineError.InvalidSelection { print("Invalid Selection.")} catch VendingMachineError.OutOfStock { print("Out of Stock.")} catch VendingMachineError.InsufficientFunds(let coinsNeeded) { print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")}
Output:
Dispensing Chips
这是无异常的输出结果,可以尝试修改成其他结果验证
2.3、将错误转换为可选值
使用try?
将错误转换为一个可选值来处理错误
如果抛出错误,那么这个表达式为nil
,否则,即正常情况就是函数的返回值
func someThrowingFunction() throws -> Int { // ...}let x = try? someThrowingFunction()let y: Int?do { y = try someThrowingFunction()} catch { y = nil}
但是不管正不正常,x、y都是可选类型
let result = try?vend.vend(itemNamed: "XXX")print(result) //结果是nil,因为货物不在清单中
Output:
nil
2.4、使错误传递失效
除try?
外还有try!
处理错误情况,但是try!
是确定没错的情况下值为函数返回值,如果出错直接崩溃。错误不会抛给catch
处理或向上抛出
3、指定清理操作
defer
语句,代码执行要离开当前代码段之前执行的一套语句。不管以何种方式离开(错误或return
或break
等),都会去执行的一些必要的清理工作
defer
关键字与要被延迟执行的语句组成
延迟执行操作是按照被指定的相反顺序执行的,譬如有两个defer
语句,那么第一条defer
在第二条defer
执行之后执行
defer
语句不一定在错误处理代码中使用,其他情况也常使用
这里的功能有点类似OC中异常处理机制中的finally
关键字
func testDefer() throws { print("111111") defer { print("Defer1") } print("222222") defer { print("Defer2") } print("333333") do { defer { print("Do-Catch Defer") } try vend.vend(itemNamed: "chippppp") } catch VendingMachineError.InvalidSelection { print("Invalid Selection.") } catch VendingMachineError.OutOfStock { print("Out of Stock.") } catch VendingMachineError.InsufficientFunds(let coinsNeeded) { print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.") }}try testDefer()
Output:
111111222222333333Do-Catch DeferInvalid Selection.Defer2Defer1
注意打印顺序,尤其Do-Catch
中的打印顺序,defer
语句先于catch
打印,可能defer
离开代码段之前的意思可能是外层{ }
,不知道这样理解对不对
如果把do中的代码顺序换下
do { try vend.vend(itemNamed: "chippppp") defer { print("Do-Catch Defer") }}
Output:
111111222222333333Invalid Selection.Defer2Defer1
会发现do
中defer
语句根本没有执行,没有打印结果,这点在以后的应用中要注意
- Swift(十八、错误处理)
- swift学习-错误处理(十八)
- swift 错误处理
- Swift 错误处理
- Swift-错误处理
- Swift 错误处理
- swift 错误处理
- Swift错误处理
- Swift 中的错误处理
- Swift基础 错误处理
- Swift错误处理(Error Handling)
- 神奇的 Swift 错误处理
- Swift初体验-错误处理
- 详解Swift中的错误处理
- swift学习错误处理流程
- Swift 协议(十八)
- Swift语法_错误处理&&断言
- 详说Swift 2.0中的错误处理
- linux环境下安装Android SDK
- 模拟退火算法的详细理解
- 内存泄漏的检测、定位和解决经验总结
- Eclipse的基本使用
- 1.如何使用VISIO画UML图
- Swift(十八、错误处理)
- web前端关于兼容性的问题。
- C++内存泄露心得
- linux RPM
- hdu1286 找朋友 (欧拉函数+素数筛法)
- 《An Industrial-Strength Audio Search Algorithm》译文
- MyEclipse配置SVN,从SVN中捡出项目
- Hibernate之QBC查询与本地SQL查询
- 象行中国9月份9个城市PPT分享(二)