【Swift】条件分岐文について〜if文〜

#if文 とは

`if文`とは制御構文の中の条件分岐文の一つです。
条件の成否に応じて実行する処理を切り替える制御構文になります。

if文は、Bool型の値を返す条件式とそれに続く{ }内の実行文で構成されます。
**条件式がtrueを返すと{ }内の処理が行われ、falseを返すと{ }内の処理が飛ばされます。**

また、条件式の返す値がBool型意外だとコンパイルエラーが起こります。

今回は、`a == 1` が条件式になります。

定数aの値は１なので、条件式は`1 == 1`となりtrueを返します。

```swift
if 条件式 {
   条件式がtrueだった場合に実行される処理
}

--------------------

let a = 1
if a == 1 {
   print("aの値は１です。")
}

実行結果
aの値は１です。
```

他にも比較演算子を使用してBool型の返り値をもらう方法もあります。
同値性や比較演算子についてわからなかったら過去の記事で説明してるのでご覧ください。


```swift
let value = 10

if value >= 5 {
   print("valueの値は５以上です。")
}

実行結果
valueの値は５以上です。
```

これだけでも十分便利なのですが、if文はまだまだ多くの機能を持っています。

##else 

if文は条件式がtrueだった場合の処理を指定する条件分岐文でした。
trueだけでなく、**条件式がfalseだった場合の処理を指定するには、if文にelseを追加します。**

```swift
if 条件式 {
   条件式がtrueだった時の処理   //falseだとこの{}内は読まれません
} else {
   条件式がfalseだった時の処理  //trueだとこの{}内は読まれません
}
```
条件式がtrueの場合は、そのすぐ次の{ }内の処理を実行。
条件式がfalseの場合は、elseの次の{ }内の処理を実行します。

つまり、必ずどちらかが実行されることになります。

今回の条件式は、valueの値が5以上かどうか比較しています。
条件式は、`4 >= 5`なのでfalseが返り値になります。

なのでelseの後の{ }内が実行されます。

```swift
let value = 4

if value >= 5 {
   print("valueの値は5以上です。")
} else {
   print("valueの値は5以下です。")
}

実行結果
valueの値は5以下です。
```

では、さらに様々な条件に分けたい時はどうするか。
方法はいくつかあります。

その中のよく使われる構文としては`else-if文`があります。

##else-if文

```swift
if 条件式１ {
   条件式１がtrueだった場合の処理
} else if 条件式２ {
   条件式１がfalseで、条件式２がtrueだった場合の処理
} else if 条件式３ {
   条件式１と条件式２がfalseで、条件式３がtrueだった場合の処理
} else {
   全ての条件式がfalseだった場合の処理
}
```
このように様々な条件を記載しそれに応じた適切な処理を実装することができます。

次のコードは、
国語のテストにて点数に応じて自動でコメントを付けてくれるコードという想定です。

```swift
let score = 70

if score == 100 {
    print("100点満点！すごい！")
} else if score >= 80 {
    print("高得点だ、次も頑張ろう！")
} else if score >= 60 {
    print("頑張ったね！")
} else if score >= 40 {
    print("もう少し頑張ろう！")
} else {
    print("赤点です。再試験を受けてください。")
}

実行結果
頑張ったね！
```
このif文において、最初に成立する条件式は３つ目になりますので、
実行結果としては「頑張ったね！」が表示されます。

if文の条件式の順番を逆に書いたとするとこうなります。

```swift
let score = 70

if score >= 40 {
    print("もう少し頑張ろう！")
} else if score >= 60 {
    print("頑張ったね！")
} else if score >= 80 {
    print("高得点だ、次も頑張ろう！")
} else if score == 100 {
    print("100点満点！すごい！")
} else {
    print("赤点です。再試験を受けてください。")
}

実行結果
もう少し頑張ろう！
```

条件式としては60点以上の処理内容が適切ですが、
条件式を記述する順番がおかしいので、２つ目よりも先に１つ目の条件式で成立します。

ただ条件式を記述するのではなく、
臨んだ処理が行われるような順で条件式を記述していきましょう。

if-elseの他にも**if文の中にif文を書いて条件を分岐することもできます。**
先ほどの国語のテストを例にします。

```swift
let score = 70

if score >= 40 {
    if score >= 60 {
        if score >= 80 {
            if score == 100 {
                print("100点満点！すごい！")
            } else {
                print("高得点だ、次も頑張ろう！")
            }
        } else {
            print("頑張ったね！")
        }
    } else {
        print("もう少し頑張ろう！")
    }
} else {
    print("赤点です。再試験を受けてください。")
}

実行結果
頑張ったね！
```

if文の中にif文を入れる`入れ子構造(ネスト)`になっております。

流れとしては、`if score >= 40`でtrueなので{ }内へ
{ }の中にはさらにif文があり`if score >= 60`でこちらもtrue
さらに{ }内にif文があり`if score >= 80`でこちらはfalse
この時にelse側の処理を実行します。つまり `print("頑張ったね！")`

ややこしいですがこのような流れになります。

一つの方法ではありますが、
どこに対しての{ }なのかがよくわからなくなり記載ミスをしてしまいがちです。
一応紹介しましたが、基本はelse-ifの方がいいと思います・・・(笑)

##if-let文

if-let文は、以前投稿したアンラップの記事で登場しております。
そうです。if-let文は**オプショナルバインディング**を行う条件分岐文ですね！

if-let文は、Optional\<Wrapped>型の値の有無に応じて分岐を行い、
値が存在する場合のは値の取り出しも同時に行います。

if-let文の構造は、ifの後に定数を宣言する形で記述します。
また、右辺にはOptional\<Wrapped>型の値を記述します。

Optional\<Wrapped>型の中に値が入っていたら定数に値を代入します。
値が入っていた時のみ{ }内を実行し、値がnilだった場合はelse以降を実行します。

**今回の定数scoreのスコープはローカルスコープで、if文の{ }内でしか使用できません。
また、scoreの型はOptional\<Int>ではなくInt型です。**

```swift
let a: Int? = 70

if let score = a {
    print(score)
} else {
    print("nilです。")
}

実行結果
70
```

if-let文では、同時に複数の値を取り出すことも可能です。
複数記述する場合は`,(カンマ)`を使用して区切ります。

また、複数指定した場合は一つでもnilが存在したらfalseになりelse側を実行します。
通常のif文でいう`&&(〜かつ)`のような役割をしています。

```swift
let a: Int? = 70
let b: Int? = 10

if let scoreA = a, let scoreB = b {
    let sum = scoreA + scoreB
    print(sum)
} else {
    print("nilです。")
}

実行結果
80
```

また、if-letの右辺ではダウンキャストを行うことも可能です。
**if-letとas?演算子を合わせることで、型による条件分岐を安全に行えます。**

正直この発想はなかったので勉強になりました！

定数aはInt方をAnyでアップキャストしていますので
ダウンキャストはInt型にしないとnilが返されます。

今回は、Int型でダウンキャストしているので、
定数scoreにはInt型の値である70が代入されます。

```swift
let a: Any = 70

if let score = a as? Int {
    print(score)
} else {
    print("nilです。")
}

実行結果
70
```

逆にString型でダウンキャストしようとするとこうなります。

```swift
let a: Any = 70

if let score = a as? String {
    print(score)
} else {
    print("nilです。")
}

実行結果
nilです。
```

String型でダウンキャストができなかったので、
定数scoreにはnilが代入されました。

ダウンキャストなどについてわからない場合は、
そちらも以前記事を投稿したのでご覧ください。

if文やオプショナルバインディングはよく使用するので
是非覚えておきましょうー！

if文関連のみでかなりのボリュームになってしまいましたが、
最後までご覧いただきありがとうございました。