錯(cuò)誤處理

throw和throws

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"
}

處理錯(cuò)誤的方式

方式一:用throwing函數(shù)傳遞錯(cuò)誤

1:為了表示一個(gè)函數(shù)、方法或構(gòu)造器可以拋出錯(cuò)誤,在函數(shù)聲明的參數(shù)
列表之后加上throws關(guān)鍵字。一個(gè)標(biāo)有throws關(guān)鍵字的函數(shù)被稱作
throwing函數(shù)。如果這個(gè)函數(shù)指明了返回值類型,throws關(guān)鍵詞需要寫在
箭頭(->)的前面

 2:throwing構(gòu)造器能像throwing函數(shù)一樣傳遞錯(cuò)誤

 struct PurchasedSnack {
   let name: String
   init(name: String, vendingMachine: VendingMachine) throws {
     try vendingMachine.vend(itemNamed: name)
       self.name = name
   }
 }

注意
只有throwing函數(shù)可以傳遞錯(cuò)誤。任何在某個(gè)非throwing函數(shù)內(nèi)部拋出
的錯(cuò)誤只能在函數(shù)內(nèi)部處理;

方式二:使用do - catch

do {
    //在 do 代碼塊中,使用 try 來標(biāo)記可能拋出錯(cuò)誤 的代碼。
    let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
    print(printerResponse)
} catch {
   在 catch 代碼塊中,除非你另外命名,否則錯(cuò)誤會(huì)自動(dòng)命名為 error , 
  這里就是用來處理do里面代碼出現(xiàn)錯(cuò)誤的時(shí)候執(zhí)行的代碼;
    print(error)
}


方式三:將錯(cuò)誤轉(zhuǎn)換成可選值

可以使用try?通過將錯(cuò)誤轉(zhuǎn)換成一個(gè)可選值來處理錯(cuò)誤。如果在評估
try?表達(dá)式時(shí)一個(gè)錯(cuò)誤被拋出,那么表達(dá)式的值就是nil;

 func someThrowingFunction() throws -> Int {
     // ...
 }

 let x = try? someThrowingFunction()

 let y: Int?

 do {
   y = try someThrowingFunction()
 } catch {
   y = nil
 }
這里x和y的處理是等效的;

方式四:禁用錯(cuò)誤傳遞

有時(shí)你知道某個(gè)throwing函數(shù)實(shí)際上在運(yùn)行時(shí)是不會(huì)拋出錯(cuò)誤的,在這
種情況下,你可以在表達(dá)式前面寫try!來禁用錯(cuò)誤傳遞,這會(huì)把調(diào)用包
裝在一個(gè)不會(huì)有錯(cuò)誤拋出的運(yùn)行時(shí)斷言中。如果真的拋出了錯(cuò)誤,你會(huì)
得到一個(gè)運(yùn)行時(shí)錯(cuò)誤;

延遲操作處理

可以使用defer語句在即將離開當(dāng)前代碼塊時(shí)執(zhí)行一系列語句。該語句讓
你能執(zhí)行一些必要的清理工作,不管是以何種方式離開當(dāng)前代碼塊的
——無論是由于拋出錯(cuò)誤而離開,還是由于諸如return或者break的語句
 defer語句將代碼的執(zhí)行延遲到當(dāng)前的作用域退出之前。該語句由defer
關(guān)鍵字和要被延遲執(zhí)行的語句組成。延遲執(zhí)行的語句不能包含任何控制
轉(zhuǎn)移語句,例如break或是return語句,或是拋出一個(gè)錯(cuò)誤。延遲執(zhí)行的
操作會(huì) 按照它們被指定時(shí)的順序的相反順序執(zhí)行——也就是說,第一
條defer語句中的代碼會(huì)在第二條defer語句中的代碼被執(zhí)行之后才執(zhí)行;

例子

 func processFile(filename: String) throws {
   if exists(filename) {
       let file = open(filename)
       defer {
         close(file)
       }
       while let line = try file.readline() { // 處理文件。
       }
     // close(file) 會(huì)在這里被調(diào)用,即作用域的最后。
 }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容