do-catch
構文の基本的な使い方は下の通りです。
ErrorType
を使った独自エラーを作り、独自エラーのthrowとcatchをする事ができます。
enum MyError: ErrorType { case Error1 case Error2 } do { let a: Int? = nil if (a == nil) { throw MyError.Error1 } } catch MyError.Error1 { print(1) } catch { print(2) }
catchに来たエラーは下のように取得できます。
enum MyError: ErrorType { case Error1 case Error2 } do { let a: Int? = nil if (a == nil) { throw MyError.Error1 } } catch let error { print("\(error)") }
メソッド中でcatch
したくない場合はメソッド定義にthrows
を付ければ良さそうです。
Javaのようにthrows
にエラータイプを指定する方法は見つかりませんでした。
func method() throws -> String { let a: Int? = nil if (a == nil) { throw MyError.Error1 } return "String" }
throws
付きのメソッドを呼び出す際はtry
とdo-catch
が必要です。
do { let str = try method() } catch { print(2) }
try!
を使えばdo-catch
は不要です。
しかしmethod内で例外が投げられた時はアプリが落ちます。
let str = try! method()
do-catch
せずに呼び出し元へエラーを伝えたい場合はメソッドにthrows
を付けます。
func method() throws { let a: Int? = nil if (a == nil) { throw MyError.Error1 } } func method2() throws { try method() } do { try method2() } catch { print(1) }
他言語のfinally
はdefer
を使って実現します。
defer
で定義された処理はブロックの最後に必ず処理されます。
下のようにdefer
に処理を登録すればmethod中で例外が発生した場合もdefer
の中身が呼ばれてくれます。
defer
はtry method()
の後ろで行っても効果は発揮しないので、そこだけ注意する必要があります。
// 1 → 2 → 3 という順番で出力される do { defer { print("2") } print("1") try method() } catch { print("3") }