使用采用“Error”協(xié)議的類型來表示錯(cuò)誤。
enum PrinterError: Error {
? case OutOfPaper
? case NoToner
? case OnFire
}
使用“throw”來拋出一個(gè)錯(cuò)誤并使用“throws”來表示一個(gè)可以拋出錯(cuò)誤的函數(shù)。如果在函數(shù)中拋出一個(gè)錯(cuò)誤,這個(gè)函數(shù)會(huì)立刻返回并且調(diào)用該函數(shù)的代碼會(huì)進(jìn)行錯(cuò)誤處理。
func send(job: Int, toPrinter printerName: String) throws -> String {
? if printerName == "Never Has Toner" {
? ? throw PrinterError.noToner
? }
? return "Job sent"
}
有多種方式可以用來進(jìn)行錯(cuò)誤處理。一種方式是使用“do-catch”。在“do”代碼塊中,使用“try”來標(biāo)記可以拋出錯(cuò)誤的代碼。在“catch”代碼塊中,除非你另外命名,否則錯(cuò)誤會(huì)自動(dòng)命名為“error”。
do {
? let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
? print(printerResponse)
} catch {
? print(error)
}
可以使用多個(gè)“catch”塊來處理特定的錯(cuò)誤。參照“switch”中的“case”風(fēng)格來寫“catch”。
do {
? let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")
? print(printerResponse)
} catch PrinterError.onFire {
? print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
? print("Printer error: \(printerError).")
} catch {
? print(error)
}
另一種處理錯(cuò)誤的方式使用“try?”將結(jié)果轉(zhuǎn)換為可選的。如果函數(shù)拋出錯(cuò)誤,該錯(cuò)誤會(huì)被拋棄并且結(jié)果為“nil”。否則的話,結(jié)果會(huì)是一個(gè)包含函數(shù)返回值的可選值。
let printerSuccess = try? send(job: 1884, toPrinter: "Mergenthaler")
let printerFailure = try? send(job: 1885, toPrinter: "Never Has Toner")
使用“defer”代碼塊來表示在函數(shù)返回前,函數(shù)中最后執(zhí)行的代碼。無論函數(shù)是否會(huì)拋出錯(cuò)誤,這段代碼都將執(zhí)行。使用“defer”,可以把函數(shù)調(diào)用之初就要執(zhí)行的代碼和函數(shù)調(diào)用結(jié)束時(shí)的掃尾代碼寫在一起,雖然這兩者的執(zhí)行時(shí)機(jī)截然不同。
var fridgeIsOpen = false
let fridgeContent = ["milk", "eggs", "leftovers"]
func fridgeContains(_ food: String) -> Bool {
? fridgeIsOpen = true
? defer {
? ? fridgeIsOpen = false
? }
? let result = fridgeContent.contains(food)
? return result
}
fridgeContains("banana")
print(fridgeIsOpen)