
主动退出程序
Fatal Errors(致命的错误)
fatalError()fatalError(<message: String>)
Assertions(断言,断言会在 Debug 模式下起作用,但是在 Release 模式中就会被忽略)
assert(<condition: Bool>)assert(<condition: Bool>, <message: String>)
Preconditions(先决条件,在 Debug 和 Release 模式下都会被执行,除非使用 -Ounchecked 进行编译)
precondition(<condition: Bool>)precondition(<condition: Bool>, <message: String>)preconditionFailure()preconditionFailure(<message: String>)
自定义错误处理
Swift 为运行时可恢复错误的抛出、捕获、传递和操作提供了支持。用于错误处理的类型都得遵守
Error协议,如枚举、结构体,throw后边表达式的返回值类型必须遵守Error协议。与 Objective-C 的错误处理不同, Swift 不会展开调用栈。
enum EnumError: Error {case Onecase Two}struct StructError: Error {var code: Intvar message: Stringvar description: String {return "[StructError] code: \(code), message: \(message)"}}func crash(number: Int) throws -> Int {if number < 0 {throw EnumError.One} else if number == 0 {throw StructError(code: 10001, message: "number is invalid.")}return number}
do {let val = try crash(number: 10)print(val)}catch EnumError.One {print("Throw1: EnumError.One !!")}catch let err as StructError {print("Throw2: \(err)")print("Throw2: \(err.code)")}catch {/// `error` 是默认提供的错误值print("Throw3: \(error)")}/**number = -1, Throw1: EnumError.One !!number = 0, Throw2: StructError(code: 10001, message: "number is invalid.")Throw2: 10001number = 10, 10*/
enum HttpError: Error {case client(statusCode: Int, statusMessage: String)case server(statusCode: Int, statusMessage: String)}func test(code: Int) throws {if code == 404 {throw HttpError.client(statusCode: 404, statusMessage: "Not Found")} else if code == 504 {throw HttpError.server(statusCode: 504, statusMessage: "Gateway Timeout")}}do {try test(code: 504)} catch HttpError.client(let statusCode, let statusMessage) {print("client error: \(statusCode) - \(statusMessage)")} catch HttpError.server(let statusCode, let statusMessage) {print("server error: \(statusCode) - \(statusMessage)")} catch {print("other error: \(error)")}
extension String: Error {}func test(code: Int) throws {if code == 404 {throw "Not Found"}}do {try test(code: 404)} catch {print("error: \(error)") // error: Not Found}
调用会抛出异常的函数时,如果调用函数没有对所有错误做处理,则调用函数也需要继续抛出异常,直到有调用函数把错误都处理好了。简单来说,即任何在非抛出函数中抛出错误都必须在函数内部进行处理。
enum MyError: Error {case error1, error2, error3}func throw1() throws {throw MyError.error3}func throw2() throws {do {try throw1()} catch MyError.error3 { // 如果这里直接就是`catch`,那么本函数无需`throws`print("error3")}}func excute() {do {try throw2()} catch {print(error)}}excute()
guard
- guard 关键字必须使用在函数中。
- guard 关键字必须和 else 同时出现。
- guard 关键字只在条件为 false 的时候才能走 else 语句
- guard 的 else 语句必须使用 return 或者 throw、fatalError 结束该作用域,不能继续执行后面的代码
extension String: Error {}func buy(productId: String, quantity: Int) throws {// 条件为假才执行 else 语句,也就是说,guard 省略了 if 为真的情况guard quantity > 0 else {throw "quantity must be more than 0"}}do {try buy(productId: "100323332", quantity: 0)} catch {print("error: \(error)")}
func login(myUsername: String?, myPassword: String?) {guard let username = myUsername, let password = myPassword else {print("Error: \(myUsername as Any), \(myPassword as Any)!")return}print("Welcome, \(username), \(password)!")}login(myUsername: "huangjian", myPassword: nil)login(myUsername: "huangjian", myPassword: "Hj123321")
[备注]:guard 和 if 的用法及区别
