列挙型の定義方法
enum ExampleEnum{ case ケース名1 case ケース名2 }
列挙型の定義は上記のようにenumキーワードの次に列挙型名(上記例ではExampleEnum)、ブロック内に列挙型の定義を記述します。
sample1-1
enum Fruit { case orange case apple case grape case banana }
sample1-1では列挙型Fruit型として、四つのケースを定義しています。列挙型名は通常最初の文字を大文字で記述します。
sample1-2
enum Fruit{ case orange,apple,grape,banana }
sample1-2のように複数のケースをコンマで区切って記述することもできます。sample1-2はsample1-1と全く同じ意味です。
列挙型のインスタンス化方法
sample2-1
enum Fruit{ case orange,apple,grape,banana } let fruit1=Fruit.orange print(fruit1) //orange
列挙型のインスタンス化は上記のように、
列挙型名.ケース名
のように記述します。「列挙型名.ケース名」これが列挙型の値です。sample2-1では定数fruit1にFruit.orangeを代入して、表示しています。
sample2-1(再掲)
enum Fruit{ case orange,apple,grape,banana } let fruit1=Fruit.orange print(fruit1) //orange
定義した列挙型(sample2-1ではFruit型)は、Int型、String型などの通常の型と同じ、新しい型を定義したことになります。定数fruit1は型注釈(型アノテーション)はありませんが、型推論によりFruit型と推測されます。
sample3-1
enum Fruit{ case orange,apple,grape,banana } var fruit1=Fruit.orange print(fruit1) fruit1 = .apple //←Fruitを省略できる。 print(fruit1) //orange //apple
4行目で列挙型Fruit型の値「Fruit.orange」を代入した時点で、変数fruit1はFruit型と型推論されますので、その後変数fruit1にFruit型の値を代入する場合は6行目のように「Fruit」を省略した書き方が可能です。
sample4-1
enum Fruit{ case orange,apple,grape,banana } var fruit1=Fruit.orange print(fruit1) fruit1 = .apple print(fruit1) //←fruit1の中身はFruit.apple switch fruit1{ case .orange: print("みかんです。") case .apple: print("りんごです。") //←が選択される。 case .grape: print("ぶどうです。") case .banana: print("バナナです。") } //りんごです。
sample4-1は、switch文を用いて列挙型の値に応じて処理を振り分けています。この場合も4行目の変数fruit1の初期化時に、fruit1の型がFruit型と推測されますので、9行目以下のswitch文のブロック内では型名「Fruit」を省略した記述ができます。
switch文ではブロック内で全てのケースを網羅する必要がありますので、sample4-2のように全てのケースが記述されていない場合コンパイルエラーとなります。
sample4-2
enum Fruit{ case orange,apple,grape,banana } var fruit1=Fruit.orange print(fruit1) fruit1 = .apple print(fruit1) switch fruit1{ case .orange: print("みかんです。") case .apple: print("りんごです。") case .grape: print("ぶどうです。") }
error: MyPlayground.playground:34:1: error: switch must be exhaustive switch fruit1{
exhaustive・・・徹底的な,余す所のない.
「switch文で全てのケースを記述する必要があるが、全て記述されていない」というエラーですね。
sample4-3
enum Fruit{ case orange,apple,grape,banana } var fruit1=Fruit.orange print(fruit1) fruit1 = .banana print(fruit1) switch fruit1{ case .orange: print("みかんです。") case .apple: print("りんごです。") case .grape: print("ぶどうです。") default : print("その他の果物です。") } //orange //banana //その他の果物です。
sample4-2でエラーが出てしまいましたが、この時最後にdeafultキーワードを用いて、それ以前のケース全てに当てはまらない場合の処理を書けばエラーは出なくなります。(sample4-3)
エラーは出なくなるんですが、「switch文で全てのケースを網羅する必要がある」というルールにより、例えば
「Fruit型に新たなケースmelonを追加したが、そのmelonケースに対応する処理を書き忘れた。」
ような場合に書き忘れをコンパイルエラーで教えてくれる、ということがあるんですね。ただdefaultキーワードを使用していると、値がFruit.melonだった時にdefaultに書かれた処理が選択されるのでエラーが出ない→書き忘れに気づかない
ということになってしまいます。ですのでdefaultキーワードはあまり使いすぎない方が良い、使う場合上記のデメリットを考慮する必要がある、ということですね。