Swiftの列挙型でループを回す
Swiftの列挙型では、C言語のように整数値を定義するだけでなく、多くのメソッドの定義やプロパティの定義等、多機能です.
また列挙型にプロトコルを適応させることができます.
値型の列挙型で、各メンバをループさせて参照したい場合、提供されているプロトコルを用いることで実現可能であることを知ったのでメモ代わりに以下に示しておきたいと思います.
ForwardIndexTypeプロトコル
デフォルトで提供されているForwardIndexTypeというプロトコルがあります.
/// Represents a discrete value in a series, where a value's /// successor, if any, is reachable by applying the value's /// `successor()` method. protocol ForwardIndexType : _ForwardIndexType { }
継承元を辿っていくと、_incrementableというプロトコルに行き着きます.
/// This protocol is an implementation detail of `ForwardIndexType`; do /// not use it directly. /// /// Its requirements are inherited by `ForwardIndexType` and thus must /// be satisfied by types conforming to that protocol. protocol _Incrementable : Equatable { /// Return the next consecutive value in a discrete sequence of /// `Self` values /// /// Requires: `self` has a well-defined successor. func successor() -> Self }
関数successorは、適合しているインスタンスの次に大きいインスタンスを返す関数です.
このプロトコルで定義されているsuccessor() -> Self
を実装することでループを回せます.
enum Fruits: ForwardIndexType { case Apple, Banana, Grape, Lemon case _dummy //Rangeを合わせるために必要 func successor() -> Fruits { if self == ._dummy { return ._dummy } return Fruits(rawValue: self.rawValue + 1)! } }
上記のようにすると、各メンバをループできます.
for fruit in Fruits.Apple .. .Lemon { print("\(fruit.rawValue)") } // 0,1,2,3
プロトコルは構造体、クラス、列挙型で適合させることが可能なので、非常に強力なものだと感じます.
また、Swift2.0からは、プロトコルに実装を持たせることができるようになるそうなので、より便利に使えそうです.