Swiftにおける「Try-Catch」
業務でプログラムを作成するとき、ユーザーからの入力やWebサービスからの返却値など中身が例外を発生させないかチェックすべき場面はたくさんある。
そういう時にC++やJavaでは「Try-Catch」を使う。Swiftでも類似の機構が導入されている。(Swift 2.0以降)
今回はそれについて基本的な流れを纏めた。
Error protocolを使ってエラー種別を定義
Developer documentのProtocol Errorに解説がある。
列挙体を定義して扱いやすくするのが基本だ。構造体を使ってもっと細かなErrorを分岐させることもできる。
例えば数を評価する単純なエラーを次のように列挙体で定義したとする。この定義時にError plotocolを使うのである。
enum SimpleError: Error {
case TooLarge
case TooSmall
}
エラーをスローする関数の定義
これを利用する関数にはthrowsキーワードをつける。この際、guardを使ってエラー種別を切り分ける。
func evaluateNumber(num: Int) throws {
guard num <= max else {
throw SimpleError.TooLarge
}
guard num >= min else {
throw SimpleError.TooSmall
}
}
何か返却値がある場合はthrowsの後ろに書く。
func evaluateNumber(num: Int) throws -> Int {
エラーを受け取る側のdo-try-catchブロック
Tryはそれを利用する関数などの中に置いたdo文の中で実行する。その結果、何らなのエラーが検出されると引き続くcatchブロックで処理をするというやり方である。
do {
try evaluateNumber(num: someInt)
} catch SimpleError.TooLarge {
//some process
} catch SimpleError.TooSmall {
//some process
} catch {
//For unknown error
}
まとめ
結局必要なものは
- エラーを分類するための列挙体、もしくは構造体
- エラーをスローする関数にguard文でエラーを切り分け、スローする部分
-
エラーを受け取る側のdo-try-catchブロック
である。
エラー処理自体は比較的単純なので、皆、押さえておいた方がいいと思う。ただネットワークを介するプログラムの場合、構造体を使ってもっとエラー原因を特定しやすいような処理を加えるのが吉だろう。