- 错误表示
- 在 Swift 中如果我们要定义一个表示错误的类型非常简单,只要遵循 Error 协议就可以了,我们通常用枚举或结构体来表示错误类型,枚举可能用的多一些,因为它能更直观的表达当前错误类型的每种错误细节。
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
抛出错误
函数、方法、初始化器都可以抛出错误。需要在参数列表后面,返回值前面加 throws 关键字。
func canThrowErrors() throws -> String
func cannotThrowErrors() -> String
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
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 vend(itemName 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
print("Dispensing \(name)")
}
}
let favoriteSnacks = ["Alice": "Chips",
"Bob": "Licorice",
"Eve": "Pretzels"]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
try vendingMachine.vend(itemName: snackName)
}
- 使用 Do-Catch 做错误处理
- 在 Swift 中我们使用 do-catch 块对错误进行捕捉,当我们在调用一个 throws 声明的函数或方法时,我们必须把调用语句放在 do 语句块中,同时 do 语法块后面紧跟着使用 catch 语句块。
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 6
do {
try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
print("Success! Yum.")
} catch VendingMachineError.invalidSelection {
print("Invalid Selection")
} catch VendingMachineError.outOfStock {
print("Out of Stock")
} catch VendingMachineError.insufficientFunds(coinsNeeded: let coinsNeed) {
print("Insufficient funds. Please insert an additional \(coinsNeed) coins")
} catch {
print("Unexpected error: \(error).")
}
- try?
- try? 会将错误转换为可选值,当调用 try? + 函数或方法语句的时候,如果函数或方法抛出错误,程序不发生崩溃,而返回一个 nil,如果没有抛出错误则返回可选值
try!
如果你确信一个函数或者方法不会抛出错误,可以使用 try! 来中断错误的传播。但是如果错误真的发生了,你会得到一个运行时错误。
指定退出的清理动作
defer 关键字:defer block 里的代码会在函数 return 之前执行,无论函数时从哪个分支 return 的,还是有 throw,还是自然而然走到最后一行。
网友评论