错误处理
Swift 在运行时提供了抛出、捕获、传递和操作可恢复错误等支持。Swift 中的错误处理涉及到错误处理模式与Cocoa有关。
表示与抛出错误
遵循Error 协议。
//表示与抛出错误
enum VendingMachineError: Error {
case invalidSelection //选择无效
case insufficientFunds(coinsNeeded: Int) //金额不足
case outOfstock //缺货
}
throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
处理错误
1.用 throwing 函数传递错误
一个 throwing 函数可以在其内部抛出错误,并将错误传递到函数被调用时的作用域。
注:只有 throwing 函数可以传递错误。任何在某个非 throwing 函数内部抛出的错误只能在函数内部处理。
throw 语句会立即退出方法.
struct Item {
var price: Int
var count: Int
}
class VedingMachine {
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 vend(itemNamed name: String) throws {
guard let 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
var newItem = item
newItem.count -= 1
inventory[name] = newItem
}
}
throwing 构造器能像 throwing 函数一样传递错误。例如下面代码中的 PurchasedSnack 构造器在构造过程中调用了 throwing 函数,并且通过传递到它的调用者来处理这些错误。
struct PurchasedSnack {
let name: String
init(name: String, vendingMachine:VedingMachine) throws {
try vendingMachine.vend(itemNamed: name)
self.name = name
}
}
2.用 Do-Catch 处理错误
一般形式:
do {
try expression
statements
} catch pattern 1 {
statements
} catch pattern 2 where condition {
statements
} catch {
statements
}
能够抛出错误的函数既可以使用 do-catch 语句处理,也可以让调用方来处理错误。如果错误传递到了顶层作用域却依然没有被处理,你会得到一个运行时错误。
3.将错误转换成可选值
try?
对所有的错误使用try?处理:
func fetchData() -> Data? {
if let data = try? fetchDataFromdisk(){
return data
}
if let data = try? fetchDataFromServer() {
return data
}
return nil
}
4. 禁用错误传递
有时你知道某个 throwing 函数实际上在运行时是不会抛出错误的,在这种情况下,你可以在表达式前面写 try! 来禁用错误传递,这会把调用包装在一个不会有错误抛出的运行时断言中。如果真的抛出了错误,你会得到一个运行时错误。
let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
指定清理操作
使用 defer 语句在即将离开当前代码块时执行一系列语句。该语句能执行一些必要的清理工作。可以用 defer 语句来确保文件描述符得以关闭,以及手动分配的内存得以释放。
defer 语句将代码的执行延迟到当前的作用域退出之前。延迟执行的操作会按照它们声明的顺序从后往前执行——也就是说,第一条 defer 语句中的代码最后才执行,第二条 defer 语句中的代码倒数第二个执行,以此类推。最后一条语句会第一个执行。
func processFile(filename: String) throw {
if exists(filename){
let file = open(filename)
defer {
close(file)
}
while let line = try file.readline() {
//处理文件
}
}
}
本文介绍Swift中的错误处理机制,包括如何定义、抛出及捕获错误,以及如何使用do-catch语句来处理错误。还展示了如何将错误转换为可选值和如何禁用错误传递。
194

被折叠的 条评论
为什么被折叠?



