Swiftでは、switchとenumの構文は、パターンマッチングの強力な機能と厳格な型安全性を実現しており、他の多くの言語の類似のものとは異なります。
CやC++、Objective-Cでは、列挙型は単なる整数値の集合を表し、switch文は値の一致を比較します。しかし、Swiftの列挙型(enum)ははるかに強力で、関連値、計算プロパティ、メソッドをサポートしています。switch文はパターンマッチングをサポートし、不完全な分岐からの保護や範囲、タプル、オプショナルなどとの操作が可能です。
従来の言語では、switchはしばしば完全性(すべてのケースを考慮すること)が欠如していることによるエラー、タイプエラー、enumケースに追加データを安全に保存できないことを引き起こします。これにより、実行時エラーが発生し、コンパイル時にはエラーが見つかりません。
Swiftでは、switchがすべてのケースを完全に処理することを求め、列挙型が@unknown defaultとして明示的にマークされていない限り、すべてのケースを網羅する必要があります。関連値を使用することで、enumケースに追加情報を優雅に保存できます。例:
enum NetworkResult { case success(Int) case failure(String) } func handle(result: NetworkResult) { switch result { case .success(let code): print("成功: \(code)") case .failure(let error): print("失敗: \(error)") } }
主な特徴:
enumのswitchでdefaultを書く必要がありますか?
いいえ、すべての列挙型のケースが明示的にカバーされている場合、defaultは必要ありません。さらに、必要がない限りdefaultを使用することはお勧めできません — コンパイラは新しいenumケースの追加に対して警告しないことがあります。
ケース間で自動的に移動するためにfallthroughを使用できますか?
はい、fallthroughというキーワードは利用可能ですが、注意が必要です。これは関連値を渡さず、こうした移動はSwiftの実際の実践であまり見られません。
switch number { case 1: print("ひとつ") fallthrough case 2: print("またはふたつ") default: print("その他") }
Swiftのenumは関連値を持つ場合、rawValueで比較できますか?
いいえ。関連値を持たないenumと明示的に指定されたrawValueを持つ列挙型のみがrawValueを使用して初期化、比較することができます。
開発者がenum NetworkResultのswitchにdefaultケースを追加したため、新しいケースを追加したときに処理ロジックが更新されず、アプリケーションが "静かに" 不正確に動作しました。
利点: ケースを追加する際のコンパイラの警告がない。
欠点: アプリケーションの実行時にエラーが発生し、ロジックが自動的に更新されない。
スタッフがenumのswitchでdefaultを放棄したため、コンパイラは新しいケースの処理が不足していることを示すことができました。
利点: エラーがコンパイル時に検出され、アプリケーションの動作がより予測可能になります。
欠点: ケースが多い場合、より多くのコードが必要ですが、信頼性が向上します。