Swift/パターン/列挙型 †enum Direction { // 列挙型Direction case Up // 列挙型のメンバ (member) case Down case Right case Left } enum Direction { case Up, Down, Right, Left } 列挙型のメンバは、たとえばDirection.Up のように「列挙型の名前」.「メンバ名」で表す。 let d = Direction.Up var x : Direction = .Right d == x // false。異なる値なので 列挙型の定義にメソッドを含めることができる。 enum Direction { case Up, Down, Right, Left func clockwise() -> Direction { // 時計回りに90度回転した方向 switch self { case .Up: return Right // 列挙型の内部ではメンバ名を直接参照できる case .Down: return Left case .Right: return Down case .Left: return Up } } } let d = Direction.Up d.clockwise() == Direction.Down // false d.clockwise().clockwise() == Direction.Down // true 一般的には "Direction.Up" と記述するが、型が推論できる場合には ".Up" と省略ができる。 さらに、列挙型の定義内部では "Up" のようにメンバ名だけて記述できる。 列挙型の内部には、格納型のプロパティは定義できないが、計算型のプロパティは定義できる。 タイププロパティは格納型、計算型どちらも定義でき、また、タイプメソッドも定義できる。 2種類の列挙型 †列挙型には次の2種類がある。
値型の列挙型 †全てのメンバが同じ型の値を持つように定義できる。 メンバの値はどれも異なっている必要がある。 enum 型名 : 実体型 { // 実体型になれるのは 整数、実数、Book値、文字列リテラルで初期化できる型のみ。 case メンバ名 = リテラル // "= リテラル"の部分はオプション case メンバ名 = リテラル ... } enum Direction : Int { case Up = 0, Down, Right, Left } let a = Direction.Right let i = a.rawValue // i = 2 (Int) let k = Direction.Down.rawValue // k = 1 (Int) 実体型 (raw type ) の値からそれに対応する列挙型のインスタンスを得るには、 rawValue: というキーワードの引数を1つ持つイニシャライザを使う。 失敗のあるイニシャライザなので nil が返ってくる可能性があり、オプショナル型となる。 let b: Direction ? = Direction(rawValue:3) b != Direction.Left // true if let c = Direction(rawValue:2) { print("\(c.rawValue)") / 2と表示される } enum Direction : Int { case Up = 0, Right, Down, Left func clockwise() -> Direction { let t = (self.rawValue + 1) % 4 // selfはインスタンス自身を表す return Direction(rawValue:t)! // nilになることはない } } 共用型の列挙型 †共用型 (union type の列挙型は、実体型を指定しないシンプルな列挙型と、 複数の異なるタプルの構造を併せ持つことができる型である。 enum 型名 { case メンバ名 タプル型宣言 case メンバ名 タプル型宣言 ... } enum WebColor { case Name (String) // 色の名前 case Code (String) // 色の名前 case White, Black, Red // よく使う色 } let background = WebColor.Name({indigo") let turquoise: WebColor = .Code("#40E0D0") let textColor = WebColor.Black 共用型の列挙型は、自分で == 演算子を定義しない限り、相互に比較できない。 if turquoise == WebColor.Code("#40E0D0") // エラー enum Ticket { case 切符(Int, Bool, 回数券: Bool) // 普通券の価格、小人、回数券 case カード(Int, Bool) // プリペイドカードの残金、小人 case 敬老パス // 敬老パス } caseに記述する括弧の内部はタプルで、項目にキーワードを付けることもできる。 switch t { // t は Ticket case let .切符(fare, flag, _): print("普通券 \(fare) "+ (flag ? "小人" : "大人")) case .敬老パス: print("敬老パス") case .カード(let r,true) where r < 110: print("カード 残金不足") // 小人の最低運賃 case .カード(let r,false) where r < 230: print("カード 残金不足") // 大人の最低運賃 case .カード: print("カード") } タプルの要素毎にletを記述することもできる。 case let .切符(fare, _, 回数券: flag): または case .切符(let fare,_, 回数券: let flag): if-case文 [式, ] case パターン = 式 [ where 式 ] if p == .カード { print("カード") } // エラー。この記述はできない。 switch p { // OK case .カード: print("カード") default: break } if case .カード = p {print("カード")} // OK if case .カード(let y,_) = t where y > 1200 { print("残金\(y)円のカード") } // where節を持つ例 |