##enumとは
特定の意味を持つ整定数の集合。一つの型として扱うことができるため、使い慣れると便利らしい。
正直なところstructなどの構造体との区別が曖昧なのでまとめながら整理していこうと思う。
##シンプルな列挙型
列挙型には値型や共用型など色々とありますが、ベースはこれです。
シンプルな列挙型は、特定の意味を持つ一つの集合を作成し一つの型として扱うことができます。
##定義方法
caseの後に任意の名前をつけます。
enum 列挙型 {
case ケース名1
case ケース名2
...
}
##使用例
方角を一つのまとまりとして定義しました。
enum Hand {
case rock
case scissors
case paper
}
以下のような書き方もできます。
enum Hand {
case rock, scissors, paper
}
各ケースは以下のようにして変数や定数に代入可能です。変数cのように型が決まっていれば「.」から記述可能です。
let a = Hand.rock
var b = Hand.sccciors
var c: Hand = .paper
a == c // false 比較も可能
メソッドの定義
列挙型はケースを定義して値を当てはめるだけなく、メソッドを組み込み、型全体としての動作や機能を表すことができます。下記では、ジャンケンの列挙型を定義し、自分がじゃんけんに勝利するメソッドを作成してみました。
enum Hand {
case rock
case scissors
case paper
func janken() -> Hand {
switch self {
case .rock: return .scissors
case .scissors: return .paper
case .paper: return .rock
}
}
}
let r = Hand.rock // rock
r.janken() // scissors
let s = Hand.scissors // scissors
s.janken() // paper
let p = Hand.paper // paper
p.janken() // rock
値型の列挙型
列挙型には、上記で扱ったものに加え、全てのケースが同じデータ型の何かしらの値を持つようになっている「値型」、各ケースが異なる型や値を持ち、インスタンスごとに値を変えることが可能な「共用型」があります。
定義方法
値の型をその列挙型の実体型(raw type)といい、各ケースに割り当てられた値を実体値(raw value) と言います。
enum 列挙型名: ローバリューの型 {
case ケース名1 = ローバリュー1
case ケース名2 = ローバリュー2
...
}
##使用例
上記で記述した列挙型Directionに値(raw value)割り振りました。ローバリューが定義されている列挙型では、ローバリューと列挙型の相互変換を行うための失敗可能イニシャライザinit?(rawValue:)とプロパティrawValueが用意されます。
enum Direction: String {
case up = "上"
case down = "下"
case right = "右"
case left = "左"
}
let a = Direction.up.rawValue // "上" ケースのローバリューを返す
let b = Direction.init(rawValue: "上") // up ローバリューが一致するケースがあればそのケースをインスタンス化
let c = Direction.init(rawValue: "斜め右") // nil 一致しなければnilを返す
##ローバリューのデフォルト値
ローバリューに対して値を設定しない場合、ローバリューの方に合わせてデフォルト値が出力されます。Int型の場合は0から1ずつプラスされた値が割り振られます。String型の場合はケース名がそのまま文字列として割り振られます。
// 型がStringの場合
enum Direction1: Int {
case up
case down
case right
case left
}
// 型がIntの場合
enum Direction2: String {
case up
case down
case right
case left
}
let a = Direction1.up // 0
let b = Direction1.down // 1
...
let c = Direction2.up // "UP"
let d = Direction2.down // "DOWN"
...
##CaseIterableプロトコル
列挙型を一つの配列として取得したい場合はCaseIterableプロトコルに準拠させることで簡単に実装することができます。配列にすることで使える幅が増えそうですね。ただ、このプロトコルはシンプルな列挙型、値型の列挙型で使用可能ですが、共用型の列挙型では使用することができません。
enum Hand :CaseIterable {
case rock
case scissors
case paper
}
Hand.allCases // [rock, scissors, paper]
// ランダムでジャンケン
let fight = Hand.allcases.randomElement()
##まとめ
次回は共用型の列挙型についてまとめてみようと思います