• Swift学习笔记(2):错误处理


    目录:

    • Error
    • do-catch
    • 断言

    Error

    在 Swift 中,错误用符合 Error 协议的类型的值来表示。这个空协议表明该类型可以用于错误处理异常。

    Swift 的枚举类型尤为适合构建一组相关的错误状态,枚举的关联值还可以提供错误状态的额外信息。

    enum VendingMachineError: Error {
        case invalidSelection                    // 选择无效
        case insufficientFunds(coinsNeeded: Int) // 金额不足
        case outOfStock                          // 缺货
    }

    抛出错误使用 throw 关键 字。

    throw VendingMachineError. insufficientFunds(coinsNeeded: 5)
    do-catch

    Swift中方法可以使用throws来抛出程序执行过程中的异常,外部可以使用 do...catch 来捕获使用try限定的方法抛出的异常。

    func makeASandwich() throws {
        // 这个函数有可能抛出错误
    }
    do { try makeASandwich() eatASandwich() } catch SandwichError.outOfCleanDishes { washDishes() } catch SandwichError.missingIngredients(let ingredients) { buyGroceries(ingredients) } catch { // 通常异常处理 }

    Swift 中的错误处理并不涉及解除调用栈,这是一个计算代价高昂的过程。就此而 言, throw 语句的性能特性是可以和 return 语句相媲美的。

    在函数声明的参数列表之后加上 throws 关键字来表示一个函数、方法或构造器可以抛出错误。如果这个函数指明了返回值类型, throws 关键词需要写在箭头( - > )的前面。

    func canThrowErrors() throws -> String
    func cannotThrowErrors() -> String
    struct PurchasedSnack {
         let name: String
         init(name: String, vendingMachine: VendingMachine) throws {
             try vendingMachine.vend(itemNamed: name)
             self.name = name
         }
    }

    可以使用 try? 通过将错误转换成一个可选值来处理错误。

    func someThrowingFunction() throws -> Int {
        // ...
    }
    let x = try? someThrowingFunction()
    func fetchData() -> Data? {
         if let data = try? fetchDataFromDisk() { return data }
         if let data = try? fetchDataFromServer() { return data }
         return nil
    }

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

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

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

    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() { 
                // 处理文件。
            }
            // close(file) 会在这里被调用,即作用域的最后。
        }
    }
    断言

    使用assert([条件表达式])全局方法在程序中判断表达式返回值是否为true来决定是否终止程序。

    let age = -3
    assert(age >= 0, "A person's age cannot be less than zero") // 触发断言
    声明:该系列内容均来自网络或电子书籍,只做学习总结!
  • 相关阅读:
    spring开发_Spring_DataSource
    spring开发_Annotation_注解
    java中子类的继承性
    spring开发_BeanFactoryPostProcessor_容器后处理器
    Caliburn笔记Presenter的管理(wpf框架)
    Caliburn笔记基本Command(wpf框架)
    Caliburn笔记Presenter与View(视图策略)(wpf框架)
    Caliburn笔记Action的创建(wpf框架)
    Caliburn笔记元数据(Metadata)管理(wpf框架)
    Caliburn笔记Action简写(wpf框架)
  • 原文地址:https://www.cnblogs.com/Youhei/p/6874783.html
Copyright © 2020-2023  润新知