美文网首页
Swift错误处理

Swift错误处理

作者: 我是繁星 | 来源:发表于2019-09-29 10:21 被阅读0次

    定义

    错误处理是响应错误以及从错误中回复的过程,那这个过程包括抛出、捕获、传递和操作可恢复错误的支持。

    讨论

    有些操作可能无法在所有的状态中都能返回一个有意义的值,当然可选类型可以帮忙表示失败的结果,但是错误处理可以让你更好的理解错误原因。
    swift关于错误处理的是协议Error,这个是一个控协议,可以通过枚举结构体遵循这个协议来实现错误处理。

    swift的异常处理有四种方式

    • 通过函数的方式传递下去
    • do-try-catch方式捕获
    • try?将错误作为可选性处理,错误时返回nil。
    • try! 断言错误不会发生,但是如果发生了会有运行时错误。

    例子

    举个自动贩卖机的例子。当我们去自动贩卖机买东西的时候,可能遇到以下问题

    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: 4)
        ]
        var coinsDesposited = 2
        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 <= coinsDesposited else {
                throw VendingMachineError.insufficientFunds(coinsNeeded: item.price-coinsDesposited)
            }
            var newItem = item
            newItem.count -= 1
            inventory[name] = newItem
            
            print("dispensing\(name)")
        }
    }
    

    由上可知,我们分别检验商品是否存在,库存是否充足以及投币是否足够。如果不满足就抛出异常。下面我们分别看一下上面说过的四种错误处理方式。
    可以看出在函数体后,返回值之前添加throws关键字表明该方法可能抛出异常。

    通过函数的方式传递下去

    比如添加了一个购买者姓名的属性,通过try + 方法调用的方式可以将异常传递下去。

     func vend(itemNamed name:String ,buyerName:String)throws{
            self.buyerName = buyerName
            try vend(itemNamed: name)
        }
    

    do-try-catch方式捕获

    var test = VendingMachine();
    do {
        try test.vend(itemNamed: "Chips")
    } catch VendingMachineError.invalidSelection {
        print("invalidSelection")
    } catch VendingMachineError.outOfStock{
        print("outOfStock")
    } catch VendingMachineError.insufficientFunds(let coinsNeeded){
        print("insufficientFunds\(coinsNeeded)")
    }
    

    通过do可以捕获捕获方法作用于内抛出的异常,catch可以以枚举的方式处理。

    try?将错误作为可选性处理,错误时返回nil。

    let x = try? test.vend(itemNamed: "Chips")
    

    通过try?的方式,当排出异常的时候x值为nil,正常可以返回一个可选型返回值。

    try! 断言错误不会发生,但是如果发生了会有运行时错误。

    let x = try! test.vend(itemNamed: "Chips")
    

    当我们断言方法不会抛出异常的时候可以用try!抛出异常的时候会有运行时错误,比较危险。

    结构体表示Error

    有些时候我们要描述的错误比较复杂,我们也可以用结构体遵循Error协议去实现异常处理。
    官方给出的例子,xml解析错误

    struct XMLParsingError: Error {
        enum ErrorKind {
            case invalidCharacter
            case mismatchedTag
            case internalError
        }
    
        let line: Int
        let column: Int
        let kind: ErrorKind
    }
    

    捕获错误

    do {
        let xmlDoc = try parse(myXMLData)
    } catch let e as XMLParsingError {
        print("Parsing error: \(e.kind) [\(e.line):\(e.column)]")
    } catch {
        print("Other error: \(error)")
    }
    

    综上swift中的错误处理是非常灵活的,可以用多种数据结构描述错误。

    相关文章

      网友评论

          本文标题:Swift错误处理

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