定義一個(gè)方法幔摸,獲取兩個(gè)數(shù)的除數(shù)摸柄,針對(duì)下面這段代碼來(lái)進(jìn)行Error的處理
func divide(_ num1: Int, _ num2: Int) -> Int {
num1 / num2
}
當(dāng) num2 為 0 的時(shí)候,上面代碼會(huì)發(fā)生運(yùn)行時(shí)錯(cuò)誤既忆,導(dǎo)致程序崩潰
為解決這個(gè)問(wèn)題驱负,我們需要在代碼中對(duì) num2 == 0 單獨(dú)做判斷,然后拋出異常信息
struct MyError: Error {
var msg: String
}
func divide(_ num1: Int, _ num2: Int) throws -> Int {
if num2 == 0 {
throw MyError.init(msg: "除數(shù)不能為0")
}
return num1 / num2
}
這樣當(dāng)調(diào)用 divide 這個(gè)方法的時(shí)候需要對(duì)有可能捕獲到的異常信息進(jìn)行處理患雇,處理方式如下
1跃脊、通過(guò) do-catch 捕捉 Error
do {
print(1)
print(try divide(10, 0))
print(2)
} catch let error as MyError {
print(3)
print(error.msg)
} catch {
print("其它錯(cuò)誤")
}
// 打印結(jié)果
1
3
除數(shù)不能為0
do catch 必須對(duì)所有可能出現(xiàn)的錯(cuò)誤結(jié)果進(jìn)行羅列,不然會(huì)報(bào)錯(cuò)苛吱,所以在上面會(huì)有 catch 打印"其他錯(cuò)誤", 如果不想對(duì)詳細(xì)錯(cuò)誤信息進(jìn)行處理酪术,也可以直接這樣寫
do {
print(try divide(10, 0))
} catch {
print("參數(shù)錯(cuò)誤")
// 在catch的作用域中自帶一個(gè)error,可以直接打印
print(error)
}
2、不捕捉Error绘雁,在當(dāng)前函數(shù)增加throws聲明橡疼,Error將自動(dòng)拋給上層函數(shù),如果最頂層函數(shù)(main函數(shù))依然沒(méi)有捕捉Error庐舟,那么程序?qū)⒔K止
func test() throws {
print(try divide(10, 0))
}
3欣除、可以使用 try? try! 調(diào)用可能會(huì)拋出Error的函數(shù),這樣就不用去處理Error
print(try? divide(10, 1))
print(try? divide(10, 0))
print(try! divide(10, 2))
print(try! divide(10, 0))
// 打印結(jié)果
Optional(10)
nil
5
崩潰
需要注意一下挪略,使用try?得到的結(jié)果是可選類型
使用try!解包可能會(huì)導(dǎo)致崩潰耻涛,除非你確定除數(shù)不是0,否則不要用
4瘟檩、assert(斷言)
斷言機(jī)制:不符合指定條件就拋出運(yùn)行時(shí)錯(cuò)誤抹缕,常用于調(diào)試(debug)階段的條件判斷
func divide(_ v1: Int, _ v2: Int) -> Int {
// 當(dāng)條件為 false時(shí),打印斷言中的拋出的錯(cuò)誤信息
assert(v2 != 0, "除數(shù)不能為0")
return v1 / v2
}
默認(rèn)情況下墨辛,Swift的斷言只會(huì)在Debug模式下生效卓研,Release模式下會(huì)忽略《么兀可手動(dòng)強(qiáng)制開(kāi)啟或者關(guān)閉奏赘,TARGETS---Building Settings---Other Swift Flags
- -assert-config Release:Debug模式下強(qiáng)制關(guān)閉斷言
-
-assert-config Debug:Release模式下強(qiáng)制開(kāi)啟斷言
5、fatalError
如果遇到嚴(yán)重問(wèn)題太惠,希望結(jié)束程序運(yùn)行磨淌,可以直接使用fatalError函數(shù)拋出錯(cuò)誤。
注:使用了fatalError函數(shù)凿渊,就不需要再寫return
func divide(_ v1: Int, _ v2: Int) -> Int {
if v2 != 0 {
return v1 / v2
}
fatalError("除數(shù)不能為0")
}
6梁只、defer
defer語(yǔ)句:用來(lái)定義以任何方式(拋錯(cuò)誤、return等)離開(kāi)代碼塊前必須要執(zhí)行的代碼埃脏,也就是說(shuō)defer語(yǔ)句將延遲至當(dāng)前作用域結(jié)束之前執(zhí)行
func open(_ filename: String) -> Int {
print("open")
return 0
}
func close(_ file: Int) {
print("close")
}
func processFile(_ filename: String) throws {
let file = open(filename)
defer {
close(file)
}
// 程序執(zhí)行到這里會(huì)停止搪锣,停止之前會(huì)調(diào)用 defer 中的 close方法
print(try divide(20, 0))
// close將會(huì)在這里調(diào)用
}