程式在執行時很多時候並不會如同開發者所想的執行,所以必須進行可控的錯誤處理,在Swift中所有的錯戶都由Error協議來指定,例如開發者可以自定義列舉來描述所需求的錯誤類型。
// 自定義的錯誤類型
enum MyError:Error {
case DesTroyError
case NormalError
case SimpleError
}
print("should Error")
// 進行錯誤的拋出
throw MyError.DesTroyError
print("finish")
上面的程式碼自定義了錯誤類型,之後透過throw來進行錯誤的拋出,需要注意的是,拋出的錯誤如果不進行處理,程式碼會斷在錯誤的地方,像以上的程式碼並不會印出finish。
函數在執行時,也可能會產生錯誤,一般會在函數內部進行解決,開發者也可以利用throws關鍵字來將此函數宣告成可拋異常函數,如此宣告則允許開發者在函數外解決函數內部拋出的錯誤。
func Myfunc(param: Bool) throws -> Void{
if param {
print("success")
}
else{
throw MyError.NormalError
}
}
上面的函數需要傳入一個bool類型的參數,當此參數為true時,執行正常的印出操作,假設為false時,函數將拋出錯誤。對於執行可拋錯誤的函數,Swift中要使用try關鍵字。try關鍵字的作用是試圖執行一個可能拋出錯誤的函數,其並不能捕獲與處理錯誤,捕獲與處理錯誤需要使用do-catch結構。
do-catch結構是Swift中處理錯誤最常用的方法,開發者需要將可能拋出錯誤的程式碼放到do之中,如果這部分有拋出錯誤,則會從catch尋找相對應的錯誤類型,如果找到對應的,則會執行其中的錯誤處理程式碼。
// 使用do-catch來進行錯誤的捕獲和處理
do{
// 將可能產生的錯誤寫在do中
try Myfunc(param: false)
// 進行錯誤類型的匹配
}catch MyError.SimpleError{
print("simpleError")
}catch MyError.NormalError{
print("normalError")
}catch MyError.DesTroyError{
print("destroyError")
// 如果前面的錯誤都沒有匹配上,就會被最後這個catch捕獲到
}catch{
print("otherError")
}
使用do-catch結構處理錯誤可以根據錯誤類型分別提供處理方案,確保整體可控性。
有些時候不需要使用到do-catch結構,開發者也可以使用Optional值,如果函數正常執行,沒有拋出錯誤,則正常返回,如果有錯誤則會返回Optional值nil,使用try?來調用函數可以將錯誤映射為Optional值。
var tmp = try? Myfunc(param: false)
if tmp == nil {
print("fail")
}else{
print("success")
}
需要注意的是,返回值Void並不是nil,Void是空類型,nil是Optional中特殊值。由於try?的存在,結合if-let 語句。
// 使用匿名關鍵字來接收返回值
if let _ = try? Myfunc(param: false) {
print("success")
}else{
print("fail")
}
除了上述兩種外,還有一種比較極端的情況,當開發者可以確定一定會拋出錯誤時,便可以使用try! 來強行終止異常的傳遞。
// 如果此函數拋出了異常,則會產生執行時的錯誤
try! Myfunc(param: true)
接下來,是泛型的介紹