【Swift】Swift5.9のIfステートメント

# この記事は何？

Appleの開発者向けドキュメント「[Swift Programming Language](https://docs.swift.org/swift-book/documentation/the-swift-programming-language)」について、5.9版で内容が追加されたIf条件分岐構文の章を独自に翻訳・解説する。

ある条件に基づいて、実行するコードを選択できると便利なことが多い。
例えば、エラーが発生したときにだけ余分なコードを実行したり、値が適正範囲を超えたらメッセージを表示したりする。
これを行うには、一部のコードに条件を設定する。

Swiftには、コードに条件を付けて実行フローの分岐を追加する方法が2つある。
ifステートメントとswitchステートメント。
ifステートメントは想定される結果からなる、いくつかの単純な条件を評価する。
switchステートメントはより多くの複雑な条件を評価する場合に適している。
また、switchステートメントは適切な実行コードの分岐を選択するために、パターンマッチングを利用できる。

# Ifステートメント

最も単純なifステートメントは、条件がひとつだけ。
その条件が`true`である場合にのみ、一連のステートメントを実行する。

```swift:単純なifステートメントの例
var temperatureInFahrenheit = 30    // 華氏温度は30度

// 温度が`32`度以下であるかどうかをチェックするifステートメント
if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
}
// "It's very cold. Consider wearing a scarf."が出力される
```

上記のifステートメントは、温度が華氏`32`度(水の凝固点)以下なら、メッセージが出力する。
それ以外の場合はメッセージを出力せずに、`if`ステートメントの終了括弧`{}`の後に続くコードが実行される。

条件が`false`の場合にコードを実行するために、ifステートメントにelse句のステートメントを提供できる。
else句のステートメントは、`else`キーワードで示す。

```swift:
temperatureInFahrenheit = 40    // 40度に上昇

// else句のあるifステートメント
if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else {
    print("It's not that cold. Wear a T-shirt.")
}
// "It's not that cold. Wear a T-shirt."が出力される
```

2つの分岐のうち、いずれか1つが必ず実行される。
気温が`40`度に上昇したため、スカーフの着用を勧めるほど寒くなくなった。
その結果、else句のステートメントが実行されるようになった。

`if`ステートメントを連鎖して、評価する条件を追加できる。

```swift:if-else ifステートメント
temperatureInFahrenheit = 90

// 「32度以下か、86度以上か、それ以外か」を評価するifステートメント
if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
    print("It's really warm. Don't forget to wear sunscreen.")
} else {
    print("It's not that cold. Wear a T-shirt.")
}
// Prints "It's really warm. Don't forget to wear sunscreen."
```

暖かい温度に対応するために、`if`ステートメントが追加された。
最後のelse句はあまり暖かくも寒くもない、それ以外の温度に応答する。

なお、最後のelse句は必須ではなく、不要なら除外できる。

```swift:
temperatureInFahrenheit = 72
if temperatureInFahrenheit <= 32 {
    print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
    print("It's really warm. Don't forget to wear sunscreen.")
}
```

`if`または`else if`の条件を引き起こすには寒すぎでも熱すぎでもない温度なので、メッセージは出力されない。

Swiftは、値を設定するときに使用できる「`if`の省略記法」がある。
以下に、コードの例に挙げる。

```swift:
let temperatureInCelsius = 25
let weatherAdvice: String    // 既定値を未設定

// 条件に基づいて、weatherAdviceの既定値を設定する
if temperatureInCelsius <= 0 {
    weatherAdvice = "It's very cold. Consider wearing a scarf."
} else if temperatureInCelsius >= 30 {
    weatherAdvice = "It's really warm. Don't forget to wear sunscreen."
} else {
    weatherAdvice = "It's not that cold. Wear a T-shirt."
}

print(weatherAdvice)
// Prints "It's not that cold. Wear a T-shirt."
```

`if`ステートメントの各分岐で、後に出力される`weatherAdvice`定数の値を設定する。

`if`式を使用して、このコードをより手短に記述する。

```swift:定数weatherAdviceに既定値を設定するif式
let weatherAdvice = if temperatureInCelsius <= 0 {
    "It's very cold. Consider wearing a scarf."
} else if temperatureInCelsius >= 30 {
    "It's really warm. Don't forget to wear sunscreen."
} else {
    "It's not that cold. Wear a T-shirt."
}

print(weatherAdvice)
// Prints "It's not that cold. Wear a T-shirt."
```

この`if`式は、各分岐に1つの値がある。
条件が`true`の分岐コードが、定数`weatherAdvice`に値を割り当てるための`if`式として使用される。
すべての`if`節には対応する`else if`節または`else`節がある。
そして、どの条件が`true`になるかに関係なく、いずれかの分岐が必ず一致して、`if`式が常に値を設定できるようにする。

割り当て構文は`if`式の外側から始まっている。
各分岐で`weatherAdvice =`を何度も記述する必要がない。
`if`式の各分岐で、定数`weatherAdvice`に設定可能な値のいずれかを生成し、その値を割り当てる。

`if`式の分岐はすべて、値が同じ型であること。
Swiftは各分岐の型を別々にチェックする。
そのため、複数の型で使用できる`nil`のような値では、Swiftが`if`式の型を自動的に決定できない。
そのような場合、型を明示する。

```swift:
// if式がオプショナルなので、定数がString?型であることを明示する
let freezeWarning: String? = if temperatureInCelsius <= 0 {
    "It's below freezing. Watch for ice!"
} else {
    nil
}
```

上記の`if`式について、最初の分岐は文字列だが、else節は`nil`。
`nil`は任意のオプショナル型の値として使用できるので、「定数`freezeWarning`が`String?`型である」ことを明示する必要がある。
これは、[型アノテーション]()で説明されている。

別の方法として、定数`freezeWarning`に型を明示するのではなく、`nil`に型を明示することもできる。

```swift:
// 定数freezeWarningに型アノテーションはない
let freezeWarning = if temperatureInCelsius <= 0 {
    "It's below freezing. Watch for ice!"
} else {
    nil as String?    // asで型を指定
}
```

以下の例では、`if`式でエラーをスローしたり、`fatalError(_:file:line:)`関数を呼び出す。
こうすることで、予期しない失敗に応答できる。

```swift:エラーをスローするif式
// 温度が100度より高いと、沸騰エラーをスロー
let weatherAdvice = if temperatureInCelsius > 100 {
    throw TemperatureError.boiling
} else {
    "It's a reasonable temperature."
}
```

この`if`式は、温度が100°C（水の沸点）よりも熱いかどうかをチェックする。
この温度が熱いと、`if`式はテキストを返す代わりに`.boiling`エラーをスローする。
`if`式はエラーをスローするが、`try`を付けない。
エラーの処理については、[エラー対処]()を参照。

if式は定数および変数に値を割り当てる時だけでなく、関数またはクロージャが返す値としても使用できる。