Error Handing

  • 使用枚举来定义多种error情况,遵循Error协议,并使用throw抛出对应错误情况

    //Representing and Throwing Errors
    enum VendingMachineError:Error {
        case invalidSelection
        case insufficientFunds(coinsNeeded: Int)
        case outOfStock
    }
    throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
    
  • 使用guard配合抛出相应异常

    //Propagating Errors Using Throwing Functions
    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 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
    
            print("Dispensing \(name)")
            
        }
      }
    
  • 使用try传递异常

    func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
        let snackName = favoriteSnacks[person] ?? "Candy Bar"
        try vendingMachine.vend(itemNamed: snackName)
    }
    
  • 使用do+try执行带有抛出异常的方法,使用catch捕获异常并加以处理

    var vendingMachine = VendingMachine.init()
    vendingMachine.coinsDeposited = 1
    do {
        try buyFavoriteSnack(person: "Alice", vendingMachine:       vendingMachine)
    } catch VendingMachineError.invalidSelection {
        print("Invalid Selection.")
    } catch VendingMachineError.outOfStock {
        print("Out of Stock")
    } catch VendingMachineError.insufficientFunds(let coinNeeded) {
        print("Insufficient funds. Please insert an additional \(coinNeeded) coins")
    }
    
  • 使用try?将返回变为可选

    //Converting Error to Optional Values
    func somtThrowingFunction() throws -> Int {
      
    }
    let x = try? somtThrowingFunction()
    let y : Int?
    do {
        try y = try somtThrowingFunction()
    } catch  {
        y = nil
    }
    
  • 使用try?同意处理多种throw错误结果处理相同时的简写

    func fetchData() -> Data? {
        if let data = try? fetchDataFromDisk() { return data }
        if let data = try? fetchDataFromSever() { return data }
        return nil 
    }
    
  • 使用try!确定不会错误时强制拆包

    //Disabling Error Propagation
    let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
    
  • 使用defer标记代码段保证无论是throw error还是break均会在defer出现的区域末尾执行代码段

    //Specifying Cleanup Actions
    func processFile(filename: String) throws {
        if exists(filename) {
            let file = open(filename)
            defer {
                close(file)
            }
            while let line = try file.readline() {
                // Work with the file.
            }
            // close(file) is called here, at the end of the scope.
        }
    }
    

    使用defer标记close操作,使需要在if段落末尾执行的close语句写在前面对应open,保证执行open就一定会执行close操作

  • 一段代码

    enum learningError: Error {
        case noMethod
        case noReading
        case noTool(toolName: String)
    }
    
    func iosDev(method: Bool, style: Bool, hasTool: Bool) throws{
        guard method else {
            throw learningError.noMethod
        }
        guard style else {
            throw learningError.noReading
        }
        guard hasTool else {
            throw learningError.noTool(toolName: "noMacBook")
        }
    }
    
    do {
        try iosDev(method: true, style: true, hasTool: false)
        print("is cool")
    } catch learningError.noMethod {
        print("no method")
    } catch learningError.noReading {
        print("no reading")
    } catch learningError.noTool(let name) {
        print("no", name)
    } catch {
        //加入空catch关闭
        //否则会报错:Errors thrown from here are not handled because the   enclosing catch is not exhaustive
    }
    
    if let result = try?iosDev(method: false, style: true, hasTool: true) {
        print("success")
    } else{
        print("failure")
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 126.析构器 在一个类实例销毁前,一个析构器会立即调用。使用deinit 关键字来表示析构器, 跟构造器写法类似...
    无沣阅读 899评论 0 4
  • 错误处理机制,在swift中的异常,必须在Controller级别给处理掉,不能再次往上抛出。 Handing E...
    离子来了阅读 350评论 0 0
  • 1、范型范型所解决的问题 函数、方法、类型:类,结构体,枚举,元组类型,协议参数,返回值,成员函数参数,成员属性类...
    我是小胡胡123阅读 933评论 0 1
  • 有句话说,上帝在你面前关上了一道门,也会为你开一扇窗。 这话,起码是局部真理。至少,明朝的宋应星会举手赞成。 28...
    未陌生过阅读 606评论 0 3
  • 我的诗 我的歌 我笔下的每一个字 像精灵一样 跳出来 在我房间的每个角落 红的、黄的、蓝的…… 发着光 开大会 与...
    单宇涵阅读 128评论 0 0

友情链接更多精彩内容