Swift 中的错误处理

一、使用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 语句
    init?(words: String) {
    guard let incantation = MagicWords(rawValue: words) else {
    return nil
    }
    self.magicWords = incantation
    }

二、自定义错误处理

do-try-catch 机制的关键字:

  • throws
  • do
  • catch
  • try
  • defer
  • ErrorType
  1. 定义错误
    enum ChangoSpellError: ErrorType {
    case HatMissingOrNotMagical
    case NoFamiliar
    case FamiliarAlreadyAToad
    case SpellFailed(reason: String)
    case SpellNotKnownToWitch
    }
  • 遵守ErrorType协议
  • 通过关联值绑定具体的错误原因
  1. 定义方法
  • 方法声明(或协议方法声明)添加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.
    }

  • 方法实现抛出错误
    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:只有参数函数抛出错误,自己才会抛出错误
    func doSomethingMagical(magicalOperation: () throws -> MagicalResult) rethrows -> MagicalResult {
    return try magicalOperation()
    }

  1. 调用方法,处理错误
    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? :将错误转换成niltry!:保证不会有错误,如果有,出现崩溃。
  1. defer:栈结构,先进后出。
    func speak() {
    defer {
    print("cackles")
    }

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

三、推荐做法

  • 确保错误命名清晰
  • 只有一个错误时使用nil
  • 超过一个错误时使用自定义错误
  • 不要让错误传递太远

参考资料

Magical Error Handling in Swift

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容