zoukankan      html  css  js  c++  java
  • 学习Swift -- 错误处理

    错误处理

    错误处理是响应错误以及从错误中返回的过程。swift提供第一类错误支持,包括在运行时抛出,捕获,传送和控制可回收错误。

    一些函数和方法不能总保证能够执行所有代码或产生有用的输出。可空类型用来表示值可能为空,但是当函数执行失败的事后,可空通常可以用来确定执行失败的原因,因此代码可以正确地响应失败。在Swift中,这叫做抛出函数或者抛出方法。

    错误的表示

    在Swift中,错误用符合ErrorType协议的值表示。 Swift枚举特别适合把一系列相关的错误组合在一起,同时可以把一些相关的值和错误关联在一起。因此编译器会为实现ErrorType协议的Swift枚举类型自动实现相应合成。

    // 模拟自动售卖机的错误情况
    enum VendingMachineError: ErrorType {
        // 商品不存在时
        case InvalidSelection
        // 投入的钱不够时
        case InsufficientFunds(required: Double)
        // 商品卖完了
        case OutOfStock
    }
    

     错误抛出 通过在函数或方法声明的参数后面加上throws关键字,表明这个函数或方法可以抛出错误。如果指定一个返回值,可以把throws关键字放在返回箭头(->)的前面。

    func canThrowError() throw -> String
    
    func cannotThrowError() -> String

    当调用一个抛出函数的时候,在调用前面加上try。这个关键字表明函数可以抛出错误。

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

    捕捉和处理错误

    使用do-catch语句来就捕获和处理错误

    do {
        try vend(itemName: "Candy Bar")
        // 如果vend会抛出错误的话,会传递到catch中
        // 可以在catch里处理发生错误后应做的事情,不会造成运行时错误
    } catch VendingMachineError.InvalidSelection {
        print("Invalid Selection")
    } catch VendingMachineError.InsufficientFunds(let amountRequired) {
        print("Insufficient funds. Please insert an additional $(amountRequired).")
    } catch VendingMachineError.OutOfStock {
        print("Out of Stock")
    }
    // Insufficient funds. Please insert an additional $0.25.
    

     注意:Swift中的错误处理和其他语言中的异常处理很像,使用了trycatchthrow关键字。但是和这些语言——包括Objective-C——不同的是,Swift不会展开调用堆栈,那会带来很大的性能损耗。因此,在Swift中throw语句的性能可以做到几乎和return语句一样。

    禁止错误传播

    在运行时,有几种情况抛出函数事实上是不会抛出错误的。在这几种情况下,你可以用forced-try表达式来调用抛出函数或方法,即使用try!来代替try

    通过try!来调用抛出函数或方法禁止了错误传送,并且把调用包装在运行时断言,这样就不会抛出错误。如果错误真的抛出了,会触发运行时错误。

    enum CustomError: ErrorType {
        case SomeError
    }
    
    func willOnlyThrowIfTrue(value: Bool) throws {
        if value { throw CustomError.SomeError }
    }
    
    do {
        try willOnlyThrowIfTrue(true)
    } catch {
        print("Error")
    }
    
    try! willOnlyThrowIfTrue(true)      // 运行时错误
    

    收尾操作

    使用defer语句来在执行一系列的语句。这样不管有没有错误发生,都可以执行一些必要的收尾操作。包括关闭打开的文件描述符以及释放所有手动分配的内存。

    defer语句把执行推迟到退出当前域的时候。defer语句包括defer关键字以及后面要执行的语句。被推迟的语句可能不包含任何将执行流程转移到外部的代码,比如break或者return语句,或者通过抛出一个错误。被推迟的操作的执行的顺序和他们定义的顺序相反,也就是说,在第一个defer语句中的代码在第二个defer语句中的代码之后执行。

    func processFile(filename: String) throws {
        if exists(filename) {
            let file = open(filename)
            defer {
                close(file)
            }
            while let line = try file.readline() {
                // 写文件
            }
            // defer中的close(file) 会在最后调用。不管有没有抛出错误
        }
    }
    
  • 相关阅读:
    Linux中将两块新硬盘合并成一个,挂载到/data目录下
    linux将硬盘格式化为xfs文件系统
    nginx配置文件
    centos 添加新硬盘,lvm对根目录扩容
    centos7重新调整分区大小
    Linux 一种调用蜂鸣器的方法
    mybatis中 keyProperty="id" 的作用
    MySQL实战45讲
    常用正则表达式最强整理(速查手册)
    linux下nacos的1.1.3版本集群部署
  • 原文地址:https://www.cnblogs.com/Alex-sk/p/5545162.html
Copyright © 2011-2022 走看看