Swift3.0学习笔记-Error Handling
https://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/ErrorHandling.html#//apple_ref/doc/uid/TP40014097-CH42-ID508
? ? ? ?跟其它語言一樣,Swift的異常處理是在程序拋出異常后的處理邏輯。 Swift提供了一流的異常拋出、捕獲和處理的能力。跟Java語言類似, Swift的異常并不是真正的程序崩潰, 而是程序運行的一個邏輯分支;Swift和Java捕獲異常的時序也是一樣的。當Swift運行時拋出異常后并沒有被處理, 那么程序就會崩潰。
? ? ? ?在Swift語言中使用Error表示異常, 作用同Java的Exception類或Object-C的NSError類。 蘋果建議使用枚舉作為異常類型(為什么不推薦用類或者結構體?答案是枚舉數據類型本身就是分成若干種情況,很適合做邏輯分支判斷條件)。
enum VendingMathineError: Error {case invalidSelectioncase insufficientFunds(coinsNeed: Int)case outOfStack } 上面聲明了枚舉類型VendingMathineError,繼承于Error。 注意Swift的所有異常類型都繼承于Error, 就像Java所有異常類都繼承于Exception一樣。
? ? ? ?類似于Java處理異常的try/catch/finally, Swift提供了try、try?、try!、catch、throw、throws關鍵字處理異常邏輯,用法跟Java也很像。
? ? ? ?如何聲明一個可能拋出異常的函數? ?在函數參數括號后面添加throws關鍵字, 跟Java語法有點像;區別是Swift的throws后面不用跟著異常類、而Java的throws后面要有異常類名稱。 你只要告訴Swift這個函數可能拋出異常就夠了,不需要說明到底是哪種異常,函數體內可以拋出任意類型的異常(肯定是繼承于Error)。
func canThrowErrors() throws -> String
func canThrowErrors(type: Int) throws -> String? {if type == 1 {throw VendingMathineError.invalidSelection}if type == 2 {throw VendingMathineError.outOfStack}if type == 3 {throw VendingMathineError.insufficientFunds(coinsNeed: 100)}return "success" }
? ? ?上面測試代碼是為了測試拋異常邏輯, 函數體寫成switch/case更好一些:)
? ? ?從canThrowErrors函數看出,當參數為1、2或3時會拋異常, 語法是throw ... 且程序會跳出函數體,語法同Java。
? ? ?Swift提供了一種類似于Java try/catch的語法, 是do(函數體內必須有try且該語句可能拋出異常)、catch。
- do {
- try expression
- statements
- } catch pattern 1 {
- statements
- } catch pattern 2 where condition {
- statements
- }
do {var data = try canThrowErrors(type: 3)print("after execute canThrowErrors")if data != nil {print("Error test data:\(data)")} } catch VendingMathineError.outOfStack {print("outOfStack") } catch VendingMathineError.invalidSelection {print("invalidSelection") } catch { //類似于Java的catch(Exception ex)print("Error") } 輸出:Error
try canThrowsErrors(type: 3)會拋出VendingMathineError.isSufficientFunds(coinsNeed:100),不屬于前2個catch類型, 而最后一個catch是捕獲所有異常, 所有會執行其函數體。
? ? ? 是不是感覺少了點什么? 對, 少了個類似于Java的finally,后面會介紹。?
? ? ? 下面再介紹一下try?和try!的用法。?
? ? ? try?后面的語句可能會拋出異常, 如果拋出異常則賦值nil給左側;如果沒拋出異常則將返回值賦給左側;
? ? ? try!取消異常捕獲邏輯,語法有點任性,相當于裸奔, 明知可能拋出異常,但自信這段代碼不會拋異常。 try!是try?的補充。你確定后面語句不會拋出異常,但真的拋出異常后程序會崩潰。不建議使用try!,有使用場景推薦使用try?
let tmpX = try? canThrowErrors(type:1)?//如果拋出異常程序正常運行并賦值nil給左側,如果沒拋異常則將返回值賦給左側
//let tmpY = try! canThrowErrors(type: 2)? //你很確定不會拋出異常時這樣用,但如果運行時拋異常會導致程序崩潰
? ? ?Swift的枚舉很強大, 它可以帶參數!!! 在拋出異常時可以攜帶參數, 這是其它語言不具備的特性。示例代碼:
enum MyError: Error {case Name(param: String)case Age(param: Int)}func testMethod() throws {throw MyError.Name(param: "zhangsan")}do {try testMethod()} catch MyError.Name(let name){print(name)} catch {print(error) //默認處理, error是編譯器添加的默認參數}
? ? ? Swift使用defer關鍵字作用同Java的finally, 即使代碼塊內有break、continue、return或者拋異常,在退出代碼塊后仍然會執行defer代碼塊。
func testDefer(_ param: Int) throws -> String {print("testDefer begin")defer {print("testDefer exit")}// do something...if param == 1 {throw VendingMathineError.invalidSelection}print("testDefer end")return "testDefer return"} let tmpZ = try? testDefer(1) ?輸出:
testDefer begin
testDefer exit
? ? 上面代碼只是為了測試,驗證函數體內拋出異常時的執行時序, 語法邏輯跟finally一模一樣。
func testDeferNormal() {print("testDefer begin")defer {print("testDefer exit")}print("testDefer end") } testDeferNormal()輸出:
testDefer begin
testDefer end
testDefer exit
Swift使用?? 提供類似于Java的 a==null? b:a的功能。
let favoriteSnacks = ["Alice": "Chips","Bob" : "Licorice","Eve" : "Pretzels", ] let snameName = favoriteSnacks["Alice"] ?? "other" //snameName等于"Chips" let otherName = favoriteSnacks["some"] ?? "other" //otherName等于“other”
小結:
1、 Swift的Error類似于Java的Exception;
2、Swift的異常都是繼承于Error類;
3、Swift使用do/catch類似于Java的try/catch;
4、Swift使用defer類似于Java的finally;
5、??等同于Java的三目運算符a==null? b:a;
6、注意try、try!和try?的用法和區別。
7、catch后不帶參數可以捕獲各種異常。
8、枚舉Error可以攜帶參數!!! 比其它語言強大之處。
總結
以上是生活随笔為你收集整理的Swift3.0学习笔记-Error Handling的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WIN7 旗舰版 万能KEY
- 下一篇: python 验证码识别