1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Swift】列挙型(enum)について

Last updated at Posted at 2022-06-07

目次

列挙型とは
定義方法
ローバリュー
連想値
CaseIterableプロトコル

列挙型とは

列挙型は値型の一種で、複数の識別子をまとめる型です。例えば季節には春夏秋冬の4種類がありますが、列挙型ではこれら4つの識別子をまとめて1つの方として扱えます。列挙型の一つ一つの識別子はケースと言います。また、春であると同時に夏であることがありえないように、ケースどうしは排他的です。

定義方法

列挙型の定義にはenumキーワードとcaseキーワードを使用します。
またインスタンス化は、列挙型名.ケース名のようにケース名を指定して行います。

enum Season {
   case spring
   case summer
   case autumn
   case winter
 }

let spring = Season.spring  // spring
let summer = Season.summer  // summer

クラスや構造体のようにイニシャライザを定義してインスタンス化を行うこともできます。
次の例では、イニシャライザinit(japaneseName:)を追加し、引数に渡された文字列に応じて各ケースをselfに代入しています。

enum Season {
   case spring
   case summer
   case autumn
   case winter

      init?(japaneseName: String) {
          switch japaneseName {
          case "春": self = .spring
          case "夏": self = .summer
          case "秋": self = .autumn
          case "冬": self = .winter
          default: return nil  // 春夏秋冬以外の場合はnilを返す
          }
      }
 }

let april = Season(japaneseName: "春")!  // spring
let august = Season(japaneseName: "夏")! // summer

ローバリュー

列挙型のケースにはそれぞれに対応する値を設定できます。この値をローバリュー(raw value)と言い、すべてのケースのローバリューの型は同じである必要があります。また、ローバリューの型に指定できるのは、数値型、String型、Character型などのリテラルに変更可能な型になります。
ローバリューを定義するには、型名の後に:とローバリューの型を記述します。

次の例では、列挙型SymbolにCharacter型のローバリュー"#"、"$"、"%"を設定します。

enum Symbol: Character {
    case sharp = "#"
    case dollar = "$"
    case percent = "%"
}

ローバリューが定義されている列挙型では、ローバリューと列挙型の相互変換を行うための失敗可能イニシャライライザinit?(reawValue:)とプロパティrawValueが暗黙的に用意されます。init?(rawValue:)は設定したローバリューと同じ型の値を引数に取り、ローバリューが一致するケースがあればそのケースをインスタンス化し、なければnilを返します。また、rawValueプロパティは、ケースのローバリューを返します。

enum Symbol: Character {
    case sharp = "#"
    case dollar = "$"
    case percent = "%"
}

let symbol1 = Symbol(rawValue: "#")  // sharp
let character1 = symbol?.rawValue    // "#"

let symbol2 = Symbol(rawValue: "&")  // nil
let character2 = symbol2?.rawValue   // nil

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

Int型やString型ではローバリューにデフォルト値が存在し、特に値を指定しない場合はデフォルトが使用されます
Int型のローバリューのデフォルト値は、最初のケースが0で、それ以降は前のケースに1を足した値となります。また、String型のローバリューの値は、ケース名をそのまま文字列にした値となります。

enum Symbol : Int {
    case sharp
    case dollar
    case percent
}

Symbol.sharp.rawValue   // 0
Symbol.dollar.rawValue  // 1
Symbol.percent.rawValue // 2
enum Symbol : String {
    case sharp
    case dollar
    case percent
}

Symbol.sharp.rawValue   // "sharp"
Symbol.dollar.rawValue  // "dollar"
Symbol.percent.rawValue // "percent"

連想値

列挙型のインスタンスは、どのケースかということに加えて、連想値(associated value)という付加情報を持つこともできます。連想値に指定できる型には制限がありません。
例えば、色の代表的な数値表現にRGB(Red,Green,Blue)とCMYK(Cyan,Magenta,Yellow,Key)がありますが、表現方法をケース、数値を連想地として表現すれば、これらを列挙型として表現できます。

enum Color {
    case rgb(Float, Float, Float)
    case cmyk(Float, 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 = rgb

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

// 実行結果  rgb: 0.0,0.33,0.66

CaseIterableプロトコル

allCasesプロパティ

列挙型を使用していると、すべてのケースを配列として取得したい場合があります。
そこでCaseIterableプロトコルへの準拠を宣言した列挙型には自動的にallCasesスタティックプロパティが追加され、このプロパティが列挙型のすべての要素を返します

enum Season: CaseIterable {
    case spring
    case summer
    case autumn
    case winter
}

Season.allCases  // [spring, summer, autumn, winter]

allCasesプロパティのコードが自動生成されない条件

通常、プロトコルに準拠するためには、プロトコルが定義しているプロパティやメソッドを実装する必要があります。しかし、上記のSeason型の例では、定義しいないにも関わらずallCasesプロパティが使用できていました。これは、連想値を持たない列挙型がCaseiterableプロトコルへの準拠を宣言した場合、その実装コードがコンパイラによって自動生成されるためです。

したがって、列挙型が連想値を持つ場合は、以下のようにallCasesプロパティを実装する必要があります。

enum Fruit: CaseIterable {
    case peach
    case apple(color: AppleColor)
    case orange

    static var allCases: [Fruit] {
        return [
            .peach,
            .apple(color: .red),
            .apple(color: .green),
            .orange
        ]
    }
}

enum AppleColor {
    case red, green
}

Fruit.allCases  // [peach, {red}, {green}, orange]

参考

・Swift実践入門 (https://gihyo.jp/book/2020/978-4-297-11213-4)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?