#author("2016-05-14T11:16:10+00:00","default:nitta","nitta")
#author("2016-05-25T05:52:48+00:00","default:nitta","nitta")
[[Swift/pattern]]

このページは以下の本を参考にしています。
 詳細Swift改訂版
 著者: 荻原剛志
 出版社: SBクリエイティブ株式会社 (2016/01/01)
 ISBN: 978-4-7973-8625-7
http://isbn.sbcr.jp/86257/


*Swift/パターン/列挙型 [#ea2ae80b]

 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種類の列挙型 [#k5b25509]
列挙型には次の2種類がある。
-値型 : 全メンバが同じデータ型の値を持つ
-共用型 : それぞれメンバが異なる構造を持ち、インスタンス毎に値を変えることのできる

***値型の列挙型 [#q52205db]

全てのメンバが同じ型の値を持つように定義できる。
メンバの値はどれも異なっている必要がある。
 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になることはない
   }
 }

***共用型の列挙型 [#fde8db42]

共用型 (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節を持つ例

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS