Help us understand the problem. What is going on with this article?

Swift の列挙型で独自クラスを Raw 値に使う

More than 5 years have passed since last update.

目的

Swift 言語の列挙型 では、各列挙子に Int 型 などの Raw 値を割り当てて、その値を使ってプログラムを制御できるようになっています。

独自のクラスでも条件を満たせば enum 型の Raw 値として利用できます。

独自クラスを Raw 値として使うための条件

* インスタンスをリテラルから変換できる
* Equatable プロトコルに準拠している

Raw 値として使えるクラスを定義する

とても簡単な例ですが、次のようにInt型 の値を保持するプロパティ value を持ったクラス swift MyLiteral を用意して、これを列挙型の Raw 値として使えるようにしました。

class MyLiteral : IntegerLiteralConvertible, Equatable {

    var value:Int

    required init(integerLiteral value: IntegerLiteralType) {

        self.value = value
    }
}

func ==(lhs: MyLiteral, rhs: MyLiteral) -> Bool {

    return lhs.value == rhs.value
}

なんらかのリテラルから変換できるようにする

今回は 整数値リテラル から変換できるクラスにするために IntegerLiteralConvertible プロトコルに準拠させています。

このプロトコルでは、イニシャライザ init(integerLiteral value: IntegerLiteralType) の実装が求められています。

リテラルというのは、たとえば整数値であれば 100 といったテキストですし、小数点数であれば 10.5 といったテキストです。文字列もリテラルで "TEXT" といったテキストになります。

Equatableプロトコル に準拠させる

また Equatable プロトコルに準拠させて、等号による一致判定ができるようにする必要があります。

このプロトコルで要求される実装は == 演算子 なので クラス定義の外側で プロトコルが求める演算子を実装しています。

独自クラスを列挙型で使う

条件を満たしたクラスは、列挙型の Raw 値として利用できます。

enum MyEnum : MyLiteral {

    case once = 1
    case twice = 2
}
  • 初期値はリテラルで設定します。
  • 整数値リテラルで扱う場合は、省略時は最初の項目に 0 が割り当てられます。

独自クラスを使った列挙型を case 文で使う

列挙型のRaw として独自クラスを使っても、列挙型の扱い方は普段と何も変わりません。

let times = MyEnum.twice

switch times {

case .once:
    println("ONCE")

case .twice:
    println("TWICE")
}

列挙子から独自クラスのインスタンスを取得

独自クラスを使った列挙型の変数からは rawValue プロパティを使ってインスタンスを取り出せます。

let raw:MyLiteral = times.rawValue

列挙子から直接、インスタンスを取り出すことも可能です。

let raw:MyLiteral = MyEnum.twice.rawValue

Raw 値から列挙子を取得

Raw 値で指定したクラスのインスタンスから、該当する列挙子を取得できます。

let value:MyEnum? = MyEnum(rawValue: raw)

このようにすると raw 変数に格納されている MyLiteral 型のインスタンスに該当する列挙子が取得できます。該当しない場合は nil が得られます。

上記の rawValue: には、インスタンス以外にリテラル値も直接指定できます。その場合は、リテラル値からインスタンスが作られた上で、該当する列挙子が探されるようです。

該当する列挙子を探すとき、その列挙型が想定するケースを順番にインスタンス化して、渡された Raw 値と == 演算子で比較し、一致したものを「該当するもの」と判断するようです。

列挙子の扱われ方

  • 列挙型の変数には リテラルの値 が格納されている様子
  • rawValue にアクセスしたときに その都度 変換イニシャライザでインスタンスが 生成 される様子

[詳細] http://ez-net.jp/article/6E/p1hF8GZD/L71D-l9SfKfl/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした