Swift 中的錯(cuò)誤處理

一、使用nil

  1. 可失敗初始化器
  • 使用工廠方法
    static func createWithMagicWords(words: String) -> Spell? {
    if let incantation = MagicWords(rawValue: words) {
    var spell = Spell()
    spell.magicWords = incantation
    return spell
    }
    else {
    return nil
    }
    }
    let first = Spell.createWithMagicWords("abracadabra")
    let second = Spell.createWithMagicWords("ascend")

  • 使用初始化器
    init?(words: String) {
    if let incantation = MagicWords(rawValue: words) {
    self.magicWords = incantation
    }
    else {
    return nil
    }
    }
    let first = Spell(words: "abracadabra")
    let second = Spell(words: "ascend")

  1. guard 語(yǔ)句
    init?(words: String) {
    guard let incantation = MagicWords(rawValue: words) else {
    return nil
    }
    self.magicWords = incantation
    }

二、自定義錯(cuò)誤處理

do-try-catch 機(jī)制的關(guān)鍵字:

  • throws
  • do
  • catch
  • try
  • defer
  • ErrorType
  1. 定義錯(cuò)誤
    enum ChangoSpellError: ErrorType {
    case HatMissingOrNotMagical
    case NoFamiliar
    case FamiliarAlreadyAToad
    case SpellFailed(reason: String)
    case SpellNotKnownToWitch
    }
  • 遵守ErrorType協(xié)議
  • 通過(guò)關(guān)聯(lián)值綁定具體的錯(cuò)誤原因
  1. 定義方法
  • 方法聲明(或協(xié)議方法聲明)添加throws
    func turnFamiliarIntoToad() throws -> Toad {
    if let hat = hat {
    if hat.isMagical { // When have you ever seen a Witch perform a spell without her magical hat on ? :]
    if let familiar = familiar { // Check if witch has a familiar
    if let toad = familiar as? Toad { // Check if familiar is already a toad - no magic required
    return toad
    } else {
    if hasSpellOfType(.PrestoChango) {
    if let name = familiar.name {
    return Toad(name: name)
    }
    }
    }
    }
    }
    }
    return Toad(name: "New Toad") // This is an entirely new Toad.
    }

  • 方法實(shí)現(xiàn)拋出錯(cuò)誤
    func turnFamiliarIntoToad() throws -> Toad {
    guard let hat = hat where hat.isMagical else {
    throw ChangoSpellError.HatMissingOrNotMagical
    }

       guard let familiar = familiar else {
         throw ChangoSpellError.NoFamiliar
       } 
       if familiar is Toad {
         throw ChangoSpellError.FamiliarAlreadyAToad
       }
       guard hasSpellOfType(.PrestoChango) else {
         throw ChangoSpellError.SpellNotKnownToWitch
       }
       
       guard let name = familiar.name else {
         let reason = "Familiar doesn’t have a name."
         throw ChangoSpellError.SpellFailed(reason: reason)
       }
       
       return Toad(name: name)
       
      }
    
  • rethrows:只有參數(shù)函數(shù)拋出錯(cuò)誤,自己才會(huì)拋出錯(cuò)誤
    func doSomethingMagical(magicalOperation: () throws -> MagicalResult) rethrows -> MagicalResult {
    return try magicalOperation()
    }

  1. 調(diào)用方法,處理錯(cuò)誤
    func handleSpellError(error: ChangoSpellError) {
    let prefix = "Spell Failed."
    switch error {
    case .HatMissingOrNotMagical:
    print("(prefix) Did you forget your hat, or does it need its batteries charged?")

       case .FamiliarAlreadyAToad:
         print("\(prefix) Why are you trying to change a Toad into a Toad?")
         
       default:
         print(prefix)
       }
     }
    
     func exampleOne() {
       print("") // Add an empty line in the debug area
       
       // 1
       let salem = Cat(name: "Salem Saberhagen")
       salem.speak()
       
       // 2
       let witchOne = Witch(name: "Sabrina", familiar: salem)
       do {
         // 3
         try witchOne.turnFamiliarIntoToad()
       }
         // 4
       catch let error as ChangoSpellError {
         handleSpellError(error)
       }
         // 5
       catch {
         print("Something went wrong, are you feeling OK?")
       }
       
     }
    
     exampleOne()
    
  • catch :模式匹配,類似switch,必須包含所有情況
  • try :正常情況;try? :將錯(cuò)誤轉(zhuǎn)換成niltry!:保證不會(huì)有錯(cuò)誤,如果有,出現(xiàn)崩潰。
  1. defer:棧結(jié)構(gòu),先進(jìn)后出。
    func speak() {
    defer {
    print("cackles")
    }

       defer {
         print("*screeches*")
       }
       
       print("Hello my pretties.")
     }
    
     speak()
    

三、推薦做法

  • 確保錯(cuò)誤命名清晰
  • 只有一個(gè)錯(cuò)誤時(shí)使用nil
  • 超過(guò)一個(gè)錯(cuò)誤時(shí)使用自定義錯(cuò)誤
  • 不要讓錯(cuò)誤傳遞太遠(yuǎn)

參考資料

Magical Error Handling in Swift

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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