1.错误的表示
Swift中用实现了Error
协议的类型表示错误,通常用枚举来表示一组错误信息。
1 2 3 4 5
| enum VendingMachineError: Error { case invalidSelection case insufficientFunds(coinsNeeded: Int) case outOfStock }
|
2.抛出错误
在方法的参数后,返回值前使用throws
标记可能方法可能抛出错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| 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)") } }
|
3.错误的处理
错误被抛出后,必须要有相应的代码块处理这个错误。可分四种处理方法:
- 将错误传递给调用此函数的代码;
- 使用do-catch语句处理错误;
- 将错误作为可选类型处理;
- 断言错误绝不会发生,万一真的发生则闪退;
错误会改变代码的执行路径,使用try
、try?
或者try!
标记可能抛出错误的地方。
1 2 3 4 5 6 7 8 9
| 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) }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| do { try expression statements } catch pattern 1 { statements } catch pattern 2 where condition { statements } catch pattern 3, pattern 4 where condition { statements } catch { statements }
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).") }
|
1 2 3 4 5 6 7 8 9 10 11 12
| func someThrowingFunction() throws -> Int { }
let x = try? someThrowingFunction()
let y: Int? do { y = try someThrowingFunction() } catch { y = nil }
|
使用try?
将可能抛出错误的方法的返回值转换成可选类型。如果未抛出错误,则try?表达式的值即为函数的值;如果抛出了错误则表达式的值为nil。
1
| let photo = try! loadImage(atPath: "./Resources/John Appleseed.jpg")
|
try!
断言此方法的调用不会出现错误,如果真的抛出错误则会报运行时错误。
4.兼容NSError
Swift中Error
可直接转换成OC中的NSError
, 如SomeError.error0 as NSError
,只是没有errorCode, domain等信息。如果想和NSError一样, 则需要实现LocalizedError
与CustomNSError
协议:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| enum SwiftError: Error, LocalizedError, CustomNSError { case error0, error1 public var errorDescription: String? { switch self { case .error0: return "error description error0" case .error1: return "error description error1" } } var errorCode: Int { switch self { case .error0: return 0 case .error1: return 1 } } public static var errorDomain: String { return "error domain SwiftError" } public var errorUserInfo: [String : Any] { switch self { case .error0: return ["info": "This is Error0"] case .error1: return ["info": "This is error1"] } } } print(SwiftError.error0 as NSError) print(SwiftError.error0.errorCode)
|