18.错误处理
2021-07-22 本文已影响0人
LucXion
表示与抛出错误
enum DataError:Error { // 遵循Error协议,最适合用枚举类型
case NotFine
case WrongCount(num:Int)// 可携带参数
}
throw DataError.WrongCount(num: 5) // 通过 throw 抛出
错误的处理方式有 4 种(不处理进程会直接中断结束):
为了表示一个函数、方法或构造器可以抛出错误,在函数声明的参数之后加上
throws
关键字。一个标有throws
关键字的函数被称作 throwing 函数。
-
把函数抛出的错误传递给调用此函数的代码
-
do-catch处理
enum MachineError:Error { // 定义错误 case worongUnknow case wrongCount case wrongMoney(lack:Int) } struct Item { // 每个商品的价格和数量 var price:Int var count:Int } struct Machine { // 自动贩售机 var commoditys = [ "water":Item.init(price: 2, count: 1), "food":Item.init(price: 10, count: 5) ] mutating func giveCommodity(money:Int,name:String) throws { // mutating改变结构体,throws 表明该函数是 throwing 函数 guard let itemCount = commoditys[name]?.count ,let itemPrice = commoditys[name]?.price else { throw MachineError.worongUnknow } guard itemCount > 0 else{ throw MachineError.wrongCount } guard money > itemPrice else { throw MachineError.wrongMoney(lack: itemPrice - money) } commoditys[name]?.count = itemCount - 1 } } func test() throws {//throws 是因为这里需要完善捕获信息 do{ try machine.giveCommodity(money: 3, name: "water")// try表示必须处理,do-catch }catch MachineError.wrongMoney{ print("2.do-catch捕获") } } var machine = Machine.init() for index in 0...1{ print("index = \(index)") do{ try test() }catch { print("1.被外部函数捕获\(error)") // 默认错误 error } } print("成功捕获错误,不会导致程序中断")
-
将错误转化为可选值(无参返回可选值类型为 " ()? ")
x
和y
有着相同的数值和等价的含义:func someThrowingFunction() throws -> Int { // ... } let x = try? someThrowingFunction() let y: Int? do { y = try someThrowingFunction() } catch { y = nil }
-
禁止错误传递
有时你知道某个
throwing
函数实际上在运行时是不会抛出错误的,在这种情况下,你可以在表达式前面写try!
来禁用错误传递,这会把调用包装在一个不会有错误抛出的运行时断言中。如果真的抛出了错误,你会得到一个运行时错误。例如,下面的代码使用了
loadImage(atPath:)
函数,该函数从给定的路径加载图片资源,如果图片无法载入则抛出一个错误。在这种情况下,因为图片是和应用绑定的,运行时不会有错误抛出,所以适合禁用错误传递。let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
defer语句
使用
defer
语句在即将离开当前代码块时执行一系列语句。该语句让你能执行一些必要的清理工作,不管是以何种方式离开当前代码块的——无论是由于抛出错误而离开,或是由于诸如return
、break
的语句。
defer
语句将代码的执行延迟到当前的作用域退出之前。该语句由defer
关键字和要被延迟执行的语句组成。延迟执行的语句不能包含任何控制转移语句,例如break
、return
语句,或是抛出一个错误。
func some() {
print("1")
defer {
print("2")
print("3")
}
print("4")
}
some() // 1,4,2,3 defer语句使用场景,比如1 = openFile,defear对应 closeFile