do-try-catchを使う例外処理~備忘録~

##例外処理の構文

他のプログラミング言語同様、例外処理を読み込むことで、ファイルの読み書きに失敗した時などに実行時エラーでプログラムが止まってしまうのを回避できます。


#1.例外処理の基本的な構文

```swift
do {
   try 例外が発生する可能性がある処理
   ステートメント
} catch {
   例外を受けて実行するステートメント
}
```
「例外が発生」とは簡単に言えば「エラーが発生」と同じですが、厳密には「Errorオブジェクトがスロー(throw)される」事を言います。tryで実行した処理がエラーにならない場合は続くステートメントを実行してdo文を抜けます。tryで実行した処理がエラーになった場合は例外(Errorオブジェクト)がスローされ、それをcatchで受け止めエラー時の対応を行なった後にdo文を抜けます。エラーが発生してもプログラムは続行します。

#2.Errorオブジェクトをユーザー定義関数でスローする
基本的にエラーが発生することが想定される部分にはdo-try-catchを利用するのがセオリーでしょう。その中でも便利なのが、自分で定義するユーザ定義関数内で想定されるエラーをスローすれば、例外処理に組み込んで安全に実行する事が可能です。

##2-1.ユーザー定義関数keyMakerで処理を追う。

引数で受け取った2つの文字列を連結してランダムに並べ替えた1個のパスワードを作るkeyMaker(_ key1:_key2)というユーザ定義関数を作ります。keyMaker()は引数のkey1,key2の値をチェックして条件に合わない時にエラーをスローします。


playground

```swift
enum KeyError: Error {
    case uniqueError
    case lengthError
}

```

##2-2.エラーをスローするユーザー関数を定義する。
エラーをスローする関数にはthrowsを付け、エラーをthrowでスローします。スローするエラーはKeyError.uniqueErrorのようにエラーのケースを指した値を使います。
KeyMaker()では、key1とkey2が同じだった時にKeyError.uniqueError、及びkey1及びkey2の文字数が5~10文字でない時にKeyError.lengthErrorをスローします。
エラーをするとその時点で処理が中断し、エラーをスローしなかった時だけ続くステートメントを実行して計算結果のresultをreturnします。(key1+key2).shuffled()は,key1とkey2を連結して作った新しい文字列を作り出します。

playground

keyMaker関数

```swift
//キーを生成するユーザー定義関数
func keyMaker(_ key1:String, _ key2:String)throws -> String {
    guard key1 != key2 else {
        //key1とkey2が同じ時のエラー
        throw KeyError.uniqueError
    }
    guard (5...10).contains(key1.count) && (5...10).contains(key2.count) else{
        //key1とkey2が5〜10文字でないエラー
        throw KeyError.lengthError
    }
    //key1とkey2をシャッフルする。
    let result = (key1 + key2).shuffled()
    return String(result)
}

```

playground

checkKeyMaker関数
この関数内でkeyMaker関数を呼び出して、keyを作成します。KeyMaker関数でthrowされた値は全てcatchで受け止めます。
エラーの種類を区別してエラーを振り分けます。
Errorオブジェクトとして定義したKeyErrorには指定した2種類のエラーしかありませんが、その他のエラーを受け止めるcatchのケースもあります。

```swift
//エラーをcatchするcheckKeyMaker関数。
func checkKeyMaker(_ key1:String, _ key2:String){
    do {
        //KeyMakerにkey1,key2を渡してthorwさせる。
        let result = try KeyMaker(key1, key2)
        //値を表示する。
        print (result)
    } catch KeyError.uniqueError {
        print("2つのキーが同じエラー")
    } catch KeyError.lengthError {
        print("文字数エラー")
    } catch {
        print("不明エラー")
    }
}

```


###コード全体


```swift
import UIKit

enum KeyError: Error {
    case uniqueError
    case lengthError
}
//キーを生成するユーザー定義関数
func KeyMaker(_ key1:String, _ key2:String)throws -> String {
    guard key1 != key2 else {
        //key1とkey2が同じ時のエラー
        throw KeyError.uniqueError
    }
    guard (5...10).contains(key1.count) && (5...10).contains(key2.count) else{
        //key1とkey2が5〜10文字でないエラー
        throw KeyError.lengthError
    }
    //key1とkey2をシャッフルする。
    let result = (key1 + key2).shuffled()
    return String(result)
}

//エラーをcatchするcheckKeyMaker関数。
func checkKeyMaker(_ key1:String, _ key2:String){
    do {
        //KeyMakerにkey1,key2を渡してthorwさせる。
        let result = try KeyMaker(key1, key2)
        //値を表示する。
        print (result)
    } catch KeyError.uniqueError {
        print("2つのキーが同じエラー")
    } catch KeyError.lengthError {
        print("文字数エラー")
    } catch {
        print("不明エラー")
    }
}

checkKeyMaker("swift", "tets")
checkKeyMaker("swift","123")
checkKeyMaker("swift", "swift")

```


結果

```swift
t3481752fwis6
文字数エラー
2つのキーが同じエラー

```


以上です。