美文网首页Swift
Swift - Error Handing

Swift - Error Handing

作者: ienos | 来源:发表于2019-05-21 10:09 被阅读0次

    响应错误以及从错误中恢复的过程

    抛出、捕获、传递、操作可回复错误

    表示与抛出错误

    Swift 中,错误用遵循 Error 空协议类型的值来表示用于错误处理
    枚举构建一组错误状态

    enum VendingMachineError: Error {
        case invalidSelection
        case insufficientFunds(coinsNeeded: Int)
        case outOfStock
    }
    // 抛出错误
    throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
    

    处理错误

    4 种错误处理的方式

    • 把函数抛出的错误传递给调用此函数的代码
    • do catch 语句处理错误
    • 将错误作为可选类型处理 try?
    • 断言此错误根本不会发生 try!

    用 throwing 函数传递错误

    一个标有关键字 throws 关键字的函数称为 throwing 函数

    • throws 关键字需要写在返回值箭头(->)的前面
    • 一个 throwing 函数可以在其内部抛出错误,并将错误传递到函数被调用时的作用域内
    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 {
                throws 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)")
        }
    }
    

    函数抛出的错误传递给调用函数的代码

    let favoriteSnacks = [
        "Alice": "Chips",
        "Bob": "Licorice",
        "Eve": "Pretzels"
    ]
    func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
        let snackName = favoriteSnacks[person] ?? "Candy Bar"
        try vendingMachine.vend(itemNamed: snackName)
    }
    

    用 Do-Catch 处理错误

    在 do 子句中的代码抛出错误,这个错误会与 catch 子句做匹配,从而决定哪条子句能处理它

    var vendingMachine = VendingMachine()
    vendingMachine.coinsDeposited = 8
    do {
        try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
        print("Success! Yum.")
    }  catch VendingMachineError.invalidSelection {
        print("Invalid Selection")
    } catch VendingMachineError.outOfstock {
        print("Insufficient funds. Please insert an additional \(coinsNeeded) coins")
    } catch { // 如果一条 catch 子句没有匹配指定模式,那么这条子句可以匹配任何错误
        print("Unexpected error: \(error).")
    }
    // 打印 Insufficient funds. Please insert an additional 2 coins
    

    将错误转换成可选值

    可以使用 try? 通过将错误转换成一个可选值来处理错误,抛出错误返回 nil

    func someThrowingFunction() throws -> Int {  
        // ...
    }
    let x = try? someThrowingFunction()
    
    let y: Int?
    do {
        y = try someThrowingFunction()
    } catch {
        y = nil
    }
    

    禁用错误传递

    断言此 throwing 函数不会抛出错误 try!,如果抛出错误,程序奔溃

    let photo = try! loadImage(atPath: "./Resource/John Appleseed.jpg")
    

    指定清理操作

    使用 defer 语句在 return 之前执行一系列代码

    • 延迟执行的语句不能包含任何控制转移语句,例如 break、return 或是抛出一个错误
    • 延迟执行操作会按照它们声明的顺序从后往前执行,也就是说第一个声明 defer 语句中的代码最后才执行
    func processFile(filename: String) throws {
        if exists(filename) {
            let file = open(fileName)
            defer {
              close(file)
            }
            while let line = try file.readline() {
                // 处理文件
            }
            // close(file) 会在这里被调用,即作用域的最后
        }
    }
    

    相关文章

      网友评论

        本文标题:Swift - Error Handing

        本文链接:https://www.haomeiwen.com/subject/wiowmqtx.html