Posted at

【Swift】列挙型


列挙型

列挙型とは値型の一種で、複数の識別子(データを識別するもの)を格納する型です。

そしてこれらの識別子はケースと呼ばれ、この各ケースは排他的な関係を保っています。

そのため、複数のケースを同時に保持したりすることができません。これは、曜日で例えると火曜日であると同時に水曜日でもあることがありえない事を想像していただけるとわかりやすいと思います。


定義方法

定義方法は下記のコードのようにenumの後に列挙型名を記述し、{}内にcaseの後にケース名を記述すれば定義完了です。

enum 列挙型名 {

case ケース名1
case ケース名2
}

サンプルコード

enum Weekday {

case sunday
case monday
case tuesday
case thursday
case friday
case saturday
}
let sunday = Weekday.sunday

print(sunday)

//実行結果
sunday

イニシャライザの利用

下記のコードのようにイニシャライザを使用し、引数に対応したケースを出力することも可能です。

このコードでは、引数に"日"を指定することでそれの英名のsundayが出力されています。

enum Weekday {

case sunday
case monday
case tuesday
case wednesday
case thursday
case friday
case saturday

init?(japaneseName: String) {
switch japaneseName {
case "日": self = .sunday
case "月": self = .monday
case "火": self = .tuesday
case "水": self = .wednesday
case "木": self = .thursday
case "金": self = .friday
case "土": self = .saturday
default: return nil
}
}
}

let sunday = Weekday(japaneseName: "日")

print(sunday)

//実行結果
Optional(Weekday.sunday)

コンピューテッドプロパティの利用

列挙型ではイニシャライザ以外にプロパティやメソッドなども使うことができます。

しかし一つ注意点として、ストアドプロパティは使用することができないので気をつけてください。

enum Weekday {

case sunday
case monday
case tuesday
case wednesday
case thursday
case friday
case saturday

//値を保持できないコンピューテッドプロパティ
var name: String {
//プロパティ内部でswitch文でcaseごとに返す値を分岐
switch self {
case .sunday: return "日"
case .monday: return "月"
case .tuesday: return "火"
case .wednesday: return "水"
case .thursday: return "木"
case .friday: return "金"
case .saturday: return "土"
}
}
}

let weekday = Weekday.monday
let name = weekday.name

print(name)

//実行結果


ローバリュー

列挙隊の各ケースには対応する値を設定することができ、その値のことをローバリューと言います。

列挙隊内の全てのローバリューの型は同一に統一することができ、Int型、Double型、String型、Character型などに指定可能です。

ローバリューの定義方法は型名の後に:(コロン)とローバリュの肩を記述すればOKです。

enum 列挙型名 : ローバリューの型 {

case ケース名1 = ローバリュー1
case ケース名2 = ローバリュー2
}

Character型での定義

下記はローバリュー#に対応したcaseを出力するコードです。

enum Symbol : Character {

case sharp = "#"
case dollar = "$"
case percent = "%"
}

let symbol = Symbol(rawValue: "#")

print(symbol)

//実行結果
sharp

ローバリューのデフォルト値

Int型とString型にはローバリューにデフォルト値が設定されており、Int型の場合最初のケースが0でそれ以降は最初のローバリューに1足していく形になります。

そのため下記のコードでは値が設定されているundefined以外のケースでは上から0、1、2というようにデフォルト値が設定されます。

enum Option : Int {

case none
case one
case two
case undefined = 999
}

Option.none.rawValue
Option.one.rawValue
Option.two.rawValue
Option.undefined.rawValue

//実行結果
0
1
2
999

String型に関してはcase名がそのままローバリューになります。

enum Direction : String {

case north
case east
case south
case west
}

Direction.north.rawValue

//実行結果
north


連想値

列挙型のインスタンスはケースの情報に加えて連想値という付加情報を保持することができます。

以下のサンプルコードでは色表現方法のRGBとCMYKを例としたものです。列挙隊から連想値を取り出すためには、switch文などでバリューバインディングパターンを使用します。

このように連想値を使用すると列挙型のインスタンスごとに違う値を保持することを可能にします。

enum Color {

case rgb(Float, Float, Float)
case cmbk(Float, Float, Float)
}

let rgb = Color.rgb(0.0, 0.33 , 0.66)
let cmyk = Color.cmyk(0.0, 0.33, 0.66, 0.99)

let color = Color.rgb(0.0, 0.33, 0.66, 0.99)

switch color {
case .rgb(let r, let g, let b):
print("r: \(r), g: \(g), b: \(b)")
case .cmyk(let c, let m, let y, let k):
print("c: \(c), m: \(m), y:\(y), k: \(k)")
}

//実行結果
r:0.0, g: 0.33, b:0.66