主动退出程序
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 One
case Two
}
struct StructError: Error {
var code: Int
var message: String
var 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: 10001
number = 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 的用法及区别