Swift错误处理
来源:互联网 发布:php arrayaccess 编辑:程序博客网 时间:2024/06/05 03:00
Swift错误处理
参考:
- Magical Error Handling in Swift
- Play-with-Swift-2/21-Error-Handling
强制退出程序
使用assert
,表达式为假,程序强制退出
assert(1>0, "Error")
assert
还有一种形式为assertionFailure
,程序走到这个函数时,程序会直接终端,并打印中断的信息
assertionFailure("failure")
注意assert
和assertionFailure
都只在开发的过程中起作用,当release程序后,assert
和assertionFailure
就自动失效了。
不过有些时候,希望程序在真正执行起来的时候,在某些情况下,遇到一些严重的错误,程序要强制退出,可以使用precondition
和fatalError
precondition(1>0, "Error")fatalError("Error")
Error
在一般的处理过程中可以返回nil
表示错误,但是只返回nil
,不能表示出错的原因。比如连接网络,如果网络连接不上,就返回一个nil
,这样做也是可以的,但是此时只是知道网络没连接上而已。至于是服务端出错还是客户端出错,就不得而知了。所以需要一套完善的错误处理机制。
1.自定义错误类型:
- 遵守
Error
协议
如下:
enum VendingError: Error{ case NoSuchItem case NotEnoughMoney(Int) case OutOfStock }
2.抛出错误,使用throws
关键字,抛出错误后,整个函数就已经结束了,所以后面就不用return
了
真正抛出异常使用throw
关键字
func vend(itemName itemName: String, money: Int) throws -> Int{ guard let item = items[itemName] else{ throw VendingMachine.VendingError.NoSuchItem } guard money >= item.price else{ throw VendingMachine.VendingError.NotEnoughMoney(item.price) } guard item.count > 0 else{ throw VendingMachine.VendingError.OutOfStock } return money - item.price } }
此时,这个函数就有两种退出的方式:
1.正确的return
2.抛出异常
错误处理
对于抛出异常的函数,就不能直接调用了,要处理异常。使用try
关键字
try!
表示坚信函数不会抛出异常,但是这样写也是有风险的。
try! machine.vend(itemName: "Coca Cola", money: pocketMoney)
try?
表示如果抛出异常,返回值为nil
。所以对于返回值可以使用解包的形式:
if let leftMoney = try? machine.vend(itemName: "Coca Cola", money: pocketMoney){}else{}
如果希望更具错误的类型,来做不同的处理。就需要使用do
、catch
关键字,如下:
do{ pocketMoney = try machine.vend(itemName: "Coca Cola", money: pocketMoney) print(pocketMoney, "Yuan left")}catch{ print("Error occured during vending")}
要处理不同类型的异常,形式如下:
do{ pocketMoney = try machine.vend(itemName: "Coca Cola", money: pocketMoney) print(pocketMoney, "Yuan left")}catch VendingMachine.VendingError.NoSuchItem{ print("No Such Item")}catch VendingMachine.VendingError.NotEnoughMoney(let price){ print("No Enough Money", price, "Yuan needed.")}catch VendingMachine.VendingError.OutOfStock{ print("Out of Stock")}catch{ print("Error occured during vending.")}
还有一种形式是:
do{ pocketMoney = try machine.vend(itemName: "Coca Cola", money: pocketMoney) print(pocketMoney, "Yuan left")}catch let error as VendingMachine.VendingError{}catch{ print("Error occured during vending.")}
defer
在其它语言中,错误处理通常有个finally
关键字,不管程序是否抛出异常,finally
中的代码都要执行。
在swift
中引入了defer
,它应该写在有可能退出这个函数的语句之前。defer
本身的意识是延迟,表示延迟执行。
func vend(itemName itemName: String, money: Int) throws -> Int{ defer { print("Hava a nice day") } guard let item = items[itemName] else{ throw VendingMachine.VendingError.NoSuchItem } ...... }
如果有多个defer,是按倒序来执行的,如下的方法:
func vend(itemName itemName: String, money: Int) throws -> Int{ defer { print("Hava a nice day") } guard let item = items[itemName] else{ throw VendingMachine.VendingError.NoSuchItem } guard money >= item.price else{ throw VendingMachine.VendingError.NotEnoughMoney(item.price) } guard item.count > 0 else{ throw VendingMachine.VendingError.OutOfStock } defer { print("Thank you") } dispenseItem(itemName: itemName) return money - item.price } private func dispenseItem(itemName: String){ items[itemName]!.count -= 1 print("Enjoy your",itemName) }
如果调用如下的方法,正常的执行,不会抛出异常:
var pocketMoney = 3try? machine.vend(itemName: "Coca Cola", money: pocketMoney)
则其输出顺序为:
Enjoy your Coca ColaThank youHava a nice day
如果调用如下方法,抛出异常:
var pocketMoney = 2try? machine.vend(itemName: "Coca Cola", money: pocketMoney)
则控制台只会输出:
Hava a nice day
这是因为抛出异常结束程序,只会找抛出异常之前的defer
语句
- swift 错误处理
- Swift(十八、错误处理)
- Swift 错误处理
- Swift-错误处理
- Swift 错误处理
- swift 错误处理
- Swift错误处理
- Swift 中的错误处理
- Swift基础 错误处理
- Swift错误处理(Error Handling)
- 神奇的 Swift 错误处理
- Swift初体验-错误处理
- 详解Swift中的错误处理
- swift学习错误处理流程
- swift学习-错误处理(十八)
- Swift语法_错误处理&&断言
- 详说Swift 2.0中的错误处理
- Swift 错误处理(Error Handling)
- mysql命令行登录的命令
- iso镜像文件怎么装系统图文操作
- 静态持续性、无链接性
- JavaScript中事件捕获和事件冒泡以及如何阻止冒泡事件和默认事件
- JAVA企业面试题精选 Hibernate 1-10
- Swift错误处理
- 猴子教你如何准备一份数据分析师简历的清单
- git pull报错:Auto Merge Failed; Fix Conflicts and Then Commit the Result.
- 关于select和insert,将一个表中的部分数据复制到另一个表中
- 在virtualenv内, 使用pip安装TensorFlow成功后,没有model目录
- 剑指offer_二叉树---二叉树的下一节点
- ssh-环境基本配置
- Intellij Idea 社区版开发java web项目
- 获取JAVA[WEB]项目相关路径的几种方法