17.错误处理 Error Handling Swift官方文档——版纳的笔记

//: Playground - noun: a place where people can play

import UIKit

// # 表示和抛出错误
// 在 Swift 中,错误表示为遵循 Error协议类型的值。这个空的协议明确了一个类型可以用于错误处理。
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": "Licorice",
    "Eve": "Pretzels"
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
    let snackName = favoriteSnacks[person] ?? "Candy Bar"
    try vendingMachine.vend(itemNamed: snackName)// try关键字表示函数能够抛出错误.而且这样的错误实际上被抛出了两次
}
// 使用do-catch.在 catch后写一个模式来明确分句可以处理哪个错误。如果一个 catch分句没有模式,这个分句就可以匹配所有错误并且绑定这个错误到本地常量 error上。
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
    try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
} catch VendingMachineError.invalidSelection {
    print("Invalid Selection.")
} catch VendingMachineError.outOfStock {
    print("Out of Stock.")
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
    print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
}
// 转换错误为可选项
func someThrowingFunction() throws -> Int {
    return 0
}
// 使用try?将所有类型错误统一处理. In the example, x and y are the same.
let x = try? someThrowingFunction()
let y: Int?
do {
    try y = someThrowingFunction()
} catch {
    y = nil
}
// 使用try!来取消错误传递,可以结合断言使用???

// # 指定清理操作
// 使用 defer语句来在代码离开当前代码块前执行语句合集。这个语句允许在以任何方式离开当前代码块前执行必须要的清理工作——无论是因为抛出了错误还是因为 return或者 break这样的语句。延迟的操作与其指定的顺序相反执行——就是说,第一个 defer语句中的代码会在第二个中代码执行完毕后执行,以此类推。

你可能感兴趣的:(17.错误处理 Error Handling Swift官方文档——版纳的笔记)