錯誤處理(Error handling)是響應(yīng)錯誤以及從錯誤中恢復(fù)的過程狠轻。
1 表示并拋出錯誤
Error
空協(xié)議表明該類型可以用于錯誤處理
enum VendingMachineError: Error {
case InvalidSelection //選擇無效
case InsufficientFunds(coinsNeeded: Int) //金額不足
case OutOfStock //缺貨
}
throw VendingMachineError.InsufficientFunds(coinsNeeded: 5)
2 處理錯誤
為了標(biāo)識出代碼中可能會拋出錯誤的地方抄伍,在調(diào)用一個能拋出錯誤的函數(shù)呢蛤、方法或者構(gòu)造器之前,加上 try 關(guān)鍵字危融,或者 try? 或 try!這種變體渡八。
四個處理錯誤的方式:
- 用throwing函數(shù)傳遞錯誤
throwing函數(shù): 在函數(shù)聲明的參數(shù)列表之后加上 throws 關(guān)鍵字,為了表示一個函數(shù)、方法或構(gòu)造器可以拋出錯誤晃跺。
func canThrowErrors() throws -> String
func cannotThrowErrors() -> String
一個 throwing 函數(shù)可以在其內(nèi)部拋出錯誤揩局,并將錯誤傳遞到函數(shù)被調(diào)用時的作用域。
只有 throwing 函數(shù)可以傳遞錯誤掀虎。任何在某個非throwing函數(shù)內(nèi)部拋出的錯誤只能在函數(shù)內(nèi)部處理凌盯。
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 dispenseSnack(snack: String) {
print("Dispensing \(snack)")
}
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
dispenseSnack(snack: 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(itemNamed: snackName)
}
// throwing構(gòu)造器能像throwing函數(shù)一樣傳遞錯誤。
struct PurchasedSnack {
let name: String
init(name: String, vendingMachine: VendingMachine) throws {
try vendingMachine.vend(itemNamed: name)
self.name = name
}
}
- 用 Do-Catch 處理錯誤
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
} catch VendingMachineError.InvalidSelection {
print("Invalid Selection.")
} catch VendingMachineError.OutOfStock {
print("Out of Stock.")
} catch VendingMachineError.InsufficientFunds(let coinsNeeded) {
print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
}
// 打印 “Insufficient funds. Please insert an additional 2 coins.”
- 將錯誤轉(zhuǎn)換成可選值
如果 someThrowingFunction() 拋出一個錯誤烹玉, x 和 y 的值是 nil驰怎,否則 x 和 y 的值就是該函數(shù)的返回值。
無論 someThrowingFunction() 的返回值類型是什么類型二打, x 和 y 都是這個類型的可選類型县忌。
x,y的兩種形式類似继效,try? 更簡潔症杏。
func someThrowingFunction() throws -> Int {
// ...
return 0
}
let x = try? someThrowingFunction()
let y: Int?
do {
y = try someThrowingFunction()
} catch {
y = nil
}
- 禁用錯誤傳遞
try!
禁止錯誤傳遞,如真有錯誤拋出瑞信,就出現(xiàn)運行錯誤厉颤。
let photo = try! loadImage("./Resources/John Appleseed.jpg")
3 指定清理操作
playground文件在andyRon/LearnSwift