美文网首页
Swift 5.x 错误处理

Swift 5.x 错误处理

作者: ShenYj | 来源:发表于2020-07-13 22:55 被阅读0次
    1. 错误表示
    • Swift中如果我们要定义一个表示错误的类型非常简单, 只要遵循Error协议就可以了, 我们通常用枚举或结构体来表示错误类型, 枚举可能用的多些, 因为它能更直观的表达当前错误类型的每种错误细节.
    enum VendingMachineError: Error {
        case invalidSelection
        case insufficientFunds(coinsNeeded: Int)
        case outOfStock
    }
    

    2. 如何抛出错误
    • 函数、方法和初始化器都可以抛出错误. 需要在参数列表后面, 返回值前面加throws关键字.
    func canThrowErrors() throws -> String
    func cannotThrowErrors() -> String
    

    e.g.

    enum VendingMachineError: Error {
        case invalidSelection
        case insufficientFunds(coinsNeeded: Int)
        case outOfStock
    }
    
    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)")
        }
    }
    
    
    let favoriteSnacks = [
        "Alice": "Chips",
        "Bob": "Libcorice",
        "Eve": "Pretzels"
    ]
    func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
        let snackName = favoriteSnacks[person] ?? "Candy Bar"
        try vendingMachine.vend(itemNamed: snackName)
    }
    
    

    3. 使用Do-Catch做错误处理
    • Swift中我们使用do-catch块对错误进行捕获, 当我们在调用一个throws声明的函数或方法时, 我们必须把调用语句放在do语句块中, 同时do语句块后面紧接着使用catch语句块.
    do {
        try <#throwing expression#>
        <#statements#>
    } catch <#pattern#> {
        <#statements#>
    } catch <#pattern#> where <#condition#> {
        <#statements#>
    } catch {
        <#statements#>
    }
    

    e.g.

    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("Out of Stock")
    } catch VendingMachineError.insufficientFunds(let coinsNeeded) {
        print("insufficientFunds funds. Please insert an additional \(coinsNeeded) coins")
    } catch {
        print("Unexpected error: \(error).")
    }
    

    4. try?
    • try?会将错误转换为可选值, 当调用try?+ 函数或方法语句时候, 如果函数或方法抛出错误, 程序不会崩溃, 而返回一个nil, 如果没有抛出错误则返回可选值.

    e.g.

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

    5. try!
    • 如果确定一个函数或者方法不会抛出错误, 可以使用try!来中断错误的传播.但是如果错误真的发生了, 就会得到一个运行时错误.

    e.g.

    let phone = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
    

    6. defer 指定退出的清理动作
    • defer关键字: defer block里的代码会在函数return之前执行, 无论函数是从哪个分支return的, 还是有throw, 还是自然而然的走到最后一行.
    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 scope.
    }
    

    相关文章

      网友评论

          本文标题:Swift 5.x 错误处理

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