Swift Error Handling

35 阅读2分钟

Swift provides first-class support for throwing, catching, propagating, and manipulating recoverable errors at runtime.

Swift中可以有4种处理error的方式,函数抛出异常,do-catch处理错误、将错误作为可选类型处理、或者直接Assert

1、throws 函数传递异常,在函数声明的参数之后加上 throws,代表函数可以抛出异常例如:

struct Item {
    var price: Int
    var count: Int
}

class TestErrorModel: NSObject {

    var inventory = [
        "Candy Bar": Item(price: 12, count: 7),
        "Chips": Item(price: 10, count: 4),
        "Pretzels": Item(price: 7, count: 11)
    ]

    var coinsDeposited = 10
    func vend(itemName 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)")
    }


}

注意:使用throws标记的函数,必须去处理这些错误,要么使用do-catch或者try?或者try!来处理,要么将错误传递下去例如下面这个函数将错误继续传递下去:

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使error继续向上传递 2、使用Do-catch来处理异常

var vendingMachine = VendingMachine()

vendingMachine.coinsDeposited = 8

do {

try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)

print("Success! Yum.")

} 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.")

} catch {
print("Unexpected error: \(error).")
}

在catch之后写一个可以匹配模式来标识处理什么样的错误,不过不需要每种case都要来处理,如果不处理会默认到catch地方例如:

do {
try nourish(with: "Beet-Flavored Chips")

} catch {
print("Unexpected non-vending-machine-related error: \(error)")
}

3、使用try?将错误转为可选值,如果抛出错误该值为nil例如:

func someThrowingFunction() throws -> Int {
    // ...
}

let x = try? someThrowingFunction()

let y: Int?
do {
    y = try someThrowingFunction()
} catch {
    y = nil
}

4、使用 try! 禁用错误传递 但是一旦抛出异常会在runtime时崩溃

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