Swift 5.1 (16) - 错误处理
2020/5/6 23:26:41
本文主要是介绍Swift 5.1 (16) - 错误处理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
级别: ★☆☆☆☆
标签:「iOS」「Swift 5.1 」「try?」「try!」「do-catch」
作者: 沐灵洛
审校: QiShare团队
错误的表示和抛出
在Swift中,错误由符合Error
协议的类型的值表示。Error
是空协议,表示类型可用于错误处理。
错误的处理
Swift中的错误处理类似于其他语言中的异常处理,使用了try
,catch
和throw
关键字。但是与许多其他语言(包括Objective-C)不一样的是,Swift中的错误处理不涉及展示函数调用的堆栈信息。因此throw
与return
语句的性能相当。
使用抛出函数来传播错误
抛出函数:函数声明中标记有throws
关键字。
在函数声明的参数(...)
后,返回箭头->
前使用throws
关键字,表示此函数,方法或初始化方法可以抛出错误。
func throwError()throws -> String func notThrowError() -> String 复制代码
抛出函数可以传播错误,通过抛出其中的错误到函数被调用的范围内。需要注意的是只有抛出函数可以传播错误。在非抛出函数内的抛出的错误必须在函数内处理。 抛出函数示例:
enum VendingMachineError : Error { case InvalidGoods//!< 商品无效 case StockInsufficient//!< 库存不足 case CoinInsufficient(coinNeeded:Int) } struct Item { var price : Int var count : Int } class VendingMachine { var coins : Int = 0 var goods : [String : Item] = [ "果粒橙": Item.init(price: 3, count: 2), "红牛": Item.init(price: 5, count: 4), "雪碧": Item.init(price: 4, count: 6)] func sell(itemName name : String , itemCount count : Int) throws -> Void { guard let item = goods[name] else { throw VendingMachineError.InvalidGoods } guard item.count > 0 && item.count > count else { throw VendingMachineError.StockInsufficient } guard item.price * count <= coins else { throw VendingMachineError.CoinInsufficient(coinNeeded: item.price * count - coins) } //可以成功购买 coins -= item.price * count goods[name] = Item.init(price: item.price, count: item.count - count) } } 复制代码
使用try
关键字调用抛出函数,以传播错误。抛出函数传播错误举例:
class Customer { var itemName : String var itemCount : Int var vendingMachine : VendingMachine //使用`try`关键字调用抛出函数,以传播错误 //可抛出的初始化方法 init(itemName:String,itemCount:Int,vendingMachine:VendingMachine) throws { try vendingMachine.sell(itemName: itemName, itemCount: itemCount) self.itemName = itemName self.itemCount = itemCount self.vendingMachine = vendingMachine } //可抛出函数 func buy() throws -> Void { try vendingMachine.sell(itemName: itemName, itemCount: itemCount) } } 复制代码
使用do-catch
处理错误
do-catch
语句处理错误的形式:
do { try expression statements } catch pattern 1 { statements } catch pattern 2 where condition { statements } catch { statements } 复制代码
进行错误处理的操作示例
class HandleError { class func test()->Void{ let vendmachine = VendingMachine() vendmachine.coins = 10 do { try vendmachine.sell(itemName: "红牛", itemCount: 5) print("购买成功") } catch VendingMachineError.InvalidGoods { print("购买失败" + "商品无效") } catch VendingMachineError.StockInsufficient { print("购买失败" + "库存不足") } catch VendingMachineError.CoinInsufficient(coinNeeded: let x){ print("购买失败" + "货币不足还需" + "\(x)个硬币") }catch{ print("购买失败") } } } 复制代码
class HandleError { class func test()->Void{ let vendmachine = VendingMachine() vendmachine.coins = 10 do { try vendmachine.sell(itemName: "红牛", itemCount: 5) print("购买成功") } catch{ print("购买失败") } } } 复制代码
判断捕获的错误类型:
class HandleError { class func test()->Void{ let vendmachine = VendingMachine() vendmachine.coins = 10 do { try vendmachine.sell(itemName: "红牛", itemCount: 5) print("购买成功") } catch is VendingMachineError { print("抛出的错误是VendingMachineError") } catch { print("抛出的错误不是VendingMachineError") } } 复制代码
将错误转换为可选值
使用try?
将错误转换为可选值来处理。如果在评估try?
表达式时抛出了错误,则表达式的值为nil
。
func someThrowingFunction() throws -> Int { // ... } let x = try? someThrowingFunction() 复制代码
展开try?
的写法:
let y: Int? do { y = try someThrowingFunction() } catch { y = nil } 复制代码
禁止错误的传播
使用try!
来禁止错误的传播,当所调用的抛出函数报错时,将触发运行时错误。
let x = try! someThrowingFunction() 复制代码
指定清理操作
使用defer
关键字可以在当前范围退出时,延迟执行指定的清理操作:比如关闭文件,清理内存等操作。不管是抛出错误还是由于返回或中断等语句离开代码块,defer
都将允许你执行其中的语句。
延迟操作语句:是由defer
关键字和稍后要执行的语句组成的。该语句中不能包括控制转移的语句,如:return
和break
;也不能抛出错误。
延迟操作语句的执行顺序和其在代码中写入的位置是相反的,也就是说最后写入的会首先被执行,依次类推。
延迟执行,在没有错误需要处理的情况下也可以使用。
func processFile(filename: String) throws { if exists(filename) { let file = open(filename) defer { close(file) } while let line = try file.readline() { } // close(file) is called here, at the end of the scope. } } 复制代码
参考资料: swift 5.1官方编程指南
了解更多iOS及相关新技术,请关注我们的公众号:
小编微信:可加并拉入《QiShare技术交流群》。
关注我们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)
推荐文章:
浅谈编译过程
深入理解HTTPS 浅谈 GPU 及 “App渲染流程”
iOS 查看及导出项目运行日志
Flutter Platform Channel 使用与源码分析
开发没切图怎么办?矢量图标(iconFont)上手指南
DarkMode、WKWebView、苹果登录是否必须适配?
奇舞团安卓团队——aTaller
奇舞周刊
这篇关于Swift 5.1 (16) - 错误处理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-10-05Swift语法学习--基于协议进行网络请求
- 2022-08-17Apple开发_Swift语言地标注释
- 2022-07-24Swift 初见
- 2022-05-22SwiftUI App 支持多语种 All In One
- 2022-05-10SwiftUI 组件参数简写 All In One
- 2022-04-14SwiftUI 学习笔记
- 2022-02-23Swift 文件夹和文件操作
- 2022-02-17Swift中使用KVO
- 2022-02-08Swift 汇编 String array
- 2022-01-30SwiftUI3.0页面反向传值