|
1 | 1 | # 制御フロー\(Control Flow\) |
2 | 2 |
|
3 | | -最終更新日: 2022/12/3 |
| 3 | +最終更新日: 2023/5/27 |
4 | 4 | 原文: https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html |
5 | 5 |
|
6 | 6 | 分岐、ループ、および早期終了を使ってコードを構造化する。 |
@@ -281,6 +281,81 @@ if temperatureInFahrenheit <= 32 { |
281 | 281 |
|
282 | 282 | この温度は、暑すぎず寒すぎない温度なので、`if` も `else if` も実行されず、何も出力しません。 |
283 | 283 |
|
| 284 | +Swift は、値を設定するときに使用できる `if` の省略記法のスペルを提供します。例えば、以下のコードを考えてみましょう: |
| 285 | + |
| 286 | +```swift |
| 287 | +let temperatureInCelsius = 25 |
| 288 | +let weatherAdvice: String |
| 289 | + |
| 290 | +if temperatureInCelsius <= 0 { |
| 291 | + weatherAdvice = "とても寒いですね。マフラーを巻いたほうがいいでしょう。" |
| 292 | +} else if temperatureInCelsius >= 30 { |
| 293 | + weatherAdvice = "とても暖かいですね。日焼け止めを忘れずにしましょう。" |
| 294 | +} else { |
| 295 | + weatherAdvice = "そんなに寒くありません。Tシャツを着ましょう。" |
| 296 | +} |
| 297 | + |
| 298 | +print(weatherAdvice) |
| 299 | +// "そんなに寒くありません。Tシャツを着ましょう。" |
| 300 | +``` |
| 301 | + |
| 302 | +ここでは、それぞれの分岐が `weatherAdvice` 定数の値を設定し、`if` 文の後で出力しています。 |
| 303 | + |
| 304 | +`if` 式と呼ばれる別の構文を使えば、このコードをより簡潔に書くことができます: |
| 305 | + |
| 306 | +```swift |
| 307 | +let weatherAdvice = if temperatureInCelsius <= 0 { |
| 308 | + "とても寒いですね。マフラーを巻いたほうがいいでしょう。" |
| 309 | +} else if temperatureInCelsius >= 30 { |
| 310 | + "とても暖かいですね。日焼け止めを忘れずにしましょう。" |
| 311 | +} else { |
| 312 | + "そんなに寒くありません。Tシャツを着ましょう。" |
| 313 | +} |
| 314 | + |
| 315 | +print(weatherAdvice) |
| 316 | +// "そんなに寒くありません。Tシャツを着ましょう。" |
| 317 | +``` |
| 318 | + |
| 319 | +この `if` 式のバージョンでは、各分岐に 1 つの値が含まれています。ある分岐の条件が真であれば、その分岐の値が `weatherAdvice` の割り当てられ、 `if` 式全体の値として使用されます。すべての `if` の分岐には対応する `else if` 分岐または `else` 分岐があり、どの条件が真であっても、必ずいずれかの分岐が一致し、`if` 式が常に値を生成します。 |
| 320 | + |
| 321 | +代入の構文は `if` 式の外側から始まるので、各分岐の中で `weatherAdvice =` を繰り返す必要はありません。その代わり、`if` 式の各分岐は `weatherAdvice` の 3 つの可能性のある値のうちの 1 つを生成し、代入後はその値を使用します。 |
| 322 | + |
| 323 | +`if` 式のすべての分岐には、同じ型の値を含む必要があります。Swift は各分岐の型を別々にチェックするので、複数の型で使用できる `nil` のような値は、Swift が `if` 式の型を自動的に決定することを妨げます。代わりに、あなたは明示的に型を指定する必要があります---例えば: |
| 324 | + |
| 325 | +```swift |
| 326 | +let freezeWarning: String? = if temperatureInCelsius <= 0 { |
| 327 | + "氷点下です。氷に注意しましょう!" |
| 328 | +} else { |
| 329 | + nil |
| 330 | +} |
| 331 | +``` |
| 332 | + |
| 333 | +上のコードでは、`if` 式の一方の分岐に `String` 値が、もう一方の分岐に `nil` 値が設定されています。`nil` 値は任意のオプショナル型の値として使用できるため、doc:TheBasics#Type-Annotations [型注釈\(Type Annotations\)](../language-guide/the-basics.md#type-annotations)にあるように、`freezeWarning` がオプショナルの文字列であることを明示的に記述する必要があります。 |
| 334 | +この型情報を提供する別の方法として、`freezeWarning` に明示的な型を提供する代わりに、`nil` に明示的な型を提供することができます: |
| 335 | + |
| 336 | + |
| 337 | +```swift |
| 338 | +let freezeWarning = if temperatureInCelsius <= 0 { |
| 339 | + "氷点下です。氷に注意しましょう!" |
| 340 | +} else { |
| 341 | + nil as String? |
| 342 | +} |
| 343 | +``` |
| 344 | + |
| 345 | +`if` 式は、予期せぬ失敗に対して、エラーを投げたり、`fatalError(_:file:line:)` のように、戻り値を返さない関数を呼び出して対応することができます。例えば、次のようなものです: |
| 346 | + |
| 347 | +```swift |
| 348 | +let weatherAdvice = if temperatureInCelsius > 100 { |
| 349 | + throw TemperatureError.boiling |
| 350 | +} else { |
| 351 | + "適度な気温ですね。" |
| 352 | +} |
| 353 | +``` |
| 354 | + |
| 355 | +この例では、`if` 式は予報気温が 100°C(水の沸点)より高いかどうかをチェックします。これほど高温になると、`if` 式はテキストの要約を返す代わりに、`.boiling` エラーを投げることになります。この `if` 式がエラーを投げる可能性があるにもかかわらず、その前に `try` を書いていません。エラーの扱いについては、[エラー処理\(Error Handling\)](../language-guide/error-handling.md)を参照してください。 |
| 356 | + |
| 357 | +上の例のように、`if` 式を代入の右辺で使うだけでなく、関数やクロージャが返す値として使うこともできます。 |
| 358 | + |
284 | 359 | ### Switch |
285 | 360 |
|
286 | 361 | `switch` 文は、複数の可能性に対してパターンマッチを使用して比較を行い、値を検討します。そして、一致した最初のパターンのコードのブロックを実行します。`switch` 文は、複数の可能性がある状態に対して `if` 文の代わりに使用することができます。 |
@@ -312,6 +387,27 @@ default: |
312 | 387 |
|
313 | 388 | `switch` 文の最初のケースは、英語アルファベットの最初の文字 `a` に合致し、2 番目のケースは最後の文字 `z` に合致します。全ての可能性がある文字をカバーしなければならないため、`a` と `z` 以外の全ての文字に対して `default` ケースを使用しています。こうすることで全てのケースを網羅できています。 |
314 | 389 |
|
| 390 | +`if` 文と同様に、`switch` 文にも式があります: |
| 391 | + |
| 392 | +```swift |
| 393 | +let anotherCharacter: Character = "a" |
| 394 | +let message = switch anotherCharacter { |
| 395 | +case "a": |
| 396 | + "アルファベットの最初の文字" |
| 397 | +case "z": |
| 398 | + "アルファベットの最後の文字" |
| 399 | +default: |
| 400 | + "その他の文字" |
| 401 | +} |
| 402 | + |
| 403 | +print(message) |
| 404 | +// "アルファベットの最初の文字" |
| 405 | +``` |
| 406 | + |
| 407 | +この例では、`switch` 式の各ケースには、そのケースが `anotherCharacter` にマッチしたときに使用される `message` の値が含まれています。`switch` は常に網羅的であるため、代入する値は必ず存在します。 |
| 408 | + |
| 409 | +`if` 式と同様に、与えられたケースに値を与える代わりに、エラーを投げたり、`fatalError(_:file:line:)` のように戻り値を返さない関数を呼び出すことができます。`switch` 式は、上の例のように代入の右辺で使ったり、関数やクロージャが返す値として使うことができます。 |
| 410 | + |
315 | 411 | #### 暗黙的にfallthroughしない\(No Implicit Fallthrough\) |
316 | 412 |
|
317 | 413 | C 言語や Objective-C と異なり、Swift の `switch` 文は、デフォルトでは、それぞれのケースの下から次のケースに行くことはありません。その代わりに、最初に合致した `switch` ケースの実行が完了すると、明示的に `break` しなくても、全体の `switch` 文も完了します。こうすることで、C 言語の `switch` 文よりも、より安全に簡単に使えるようにしています。間違って 1 つ以上のケースを実行してしまうリスクを防ぎます。 |
|
0 commit comments