美文网首页
18.错误处理

18.错误处理

作者: LucXion | 来源:发表于2021-07-22 11:26 被阅读0次

表示与抛出错误

enum DataError:Error { // 遵循Error协议,最适合用枚举类型
    case NotFine
    case WrongCount(num:Int)// 可携带参数
}
throw DataError.WrongCount(num: 5) // 通过 throw 抛出

错误的处理方式有 4 种(不处理进程会直接中断结束):

为了表示一个函数、方法或构造器可以抛出错误,在函数声明的参数之后加上 throws 关键字。一个标有 throws关键字的函数被称作 throwing 函数

  1. 把函数抛出的错误传递给调用此函数的代码

  2. do-catch处理

    enum MachineError:Error { // 定义错误
        case worongUnknow 
        case wrongCount 
        case wrongMoney(lack:Int) 
    }
    struct Item { // 每个商品的价格和数量
        var price:Int
        var count:Int
    }
    struct  Machine { // 自动贩售机
        var commoditys = [
            "water":Item.init(price: 2, count: 1),
            "food":Item.init(price: 10, count: 5)
        ]
        mutating func giveCommodity(money:Int,name:String) throws { // mutating改变结构体,throws 表明该函数是 throwing 函数
            guard let itemCount = commoditys[name]?.count ,let itemPrice = commoditys[name]?.price else {
                throw MachineError.worongUnknow
            }
            guard itemCount > 0 else{
                throw MachineError.wrongCount
            }
            guard money > itemPrice else {
                throw MachineError.wrongMoney(lack: itemPrice - money)
            }
            commoditys[name]?.count = itemCount - 1
        }
    }
    func test() throws {//throws 是因为这里需要完善捕获信息
        do{
            try machine.giveCommodity(money: 3, name: "water")// try表示必须处理,do-catch
        }catch MachineError.wrongMoney{
            print("2.do-catch捕获")
        }
    }
    
    var machine = Machine.init()
    for index in 0...1{
        print("index = \(index)")
        do{
            try test()
        }catch {
            print("1.被外部函数捕获\(error)") // 默认错误 error
        }
    }
    print("成功捕获错误,不会导致程序中断")
    
  3. 将错误转化为可选值(无参返回可选值类型为 " ()? ")

    xy 有着相同的数值和等价的含义:

    func someThrowingFunction() throws -> Int {
        // ...
    }
    let x = try? someThrowingFunction()
    
    let y: Int?
    do {
        y = try someThrowingFunction()
    } catch {
        y = nil
    }
    
  4. 禁止错误传递

    有时你知道某个 throwing 函数实际上在运行时是不会抛出错误的,在这种情况下,你可以在表达式前面写 try!来禁用错误传递,这会把调用包装在一个不会有错误抛出的运行时断言中。如果真的抛出了错误,你会得到一个运行时错误。

    例如,下面的代码使用了 loadImage(atPath:) 函数,该函数从给定的路径加载图片资源,如果图片无法载入则抛出一个错误。在这种情况下,因为图片是和应用绑定的,运行时不会有错误抛出,所以适合禁用错误传递。

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

defer语句

使用 defer 语句在即将离开当前代码块时执行一系列语句。该语句让你能执行一些必要的清理工作,不管是以何种方式离开当前代码块的——无论是由于抛出错误而离开,或是由于诸如 returnbreak 的语句。

defer 语句将代码的执行延迟到当前的作用域退出之前。该语句由 defer 关键字和要被延迟执行的语句组成。延迟执行的语句不能包含任何控制转移语句,例如 breakreturn 语句,或是抛出一个错误。

func some() {
    print("1")
    defer {
        print("2")
        print("3")
    }
    print("4")
}
some() // 1,4,2,3 defer语句使用场景,比如1 = openFile,defear对应 closeFile

相关文章

网友评论

      本文标题:18.错误处理

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