2014年6月3日火曜日

Swift言語の入門 (2) 列挙型編

早速ですが横道にそれていきたいと思います。個人的にSwift言語で「これは!」と思ったポイントに、列挙型の強化があります。いままでObjective-Cでは、定数をまとめてたくさん変数するための構文、程度の認識が強かった列挙型ですが、Swiftではメソッドを持つことができるようになる等、大幅に強化されました。

1.列挙型

  • enum CompassPoint {
  • case North
  • case South
  • case East
  • case West
  • }

これはシンプルなサンプルですが、方位を列挙するためのenumです。それぞれの値は、CやObjective-Cとは異なり、int型が勝手に割り当てられたりすることはありません。

  • switch directionToHead {
  • case .North:
  • println("Lots of planets have a north")
  • case .South:
  • println("Watch out for penguins")
  • case .East:
  • println("Where the sun rises")
  • case .West:
  • println("Where the skies are blue")
  • }

もちろんswitch文を使って分岐処理を書くことができます。

他にも、列挙型自体が関数を持つことができ、値のそれぞれを一つのオブジェクトのように扱うことができるようになりました。

  • enum Rank: Int {
  • case Ace = 1
  • case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
  • case Jack, Queen, King
  • func simpleDescription() -> String {
  • switch self {
  • case .Ace:
  • return "ace"
  • case .Jack:
  • return "jack"
  • case .Queen:
  • return "queen"
  • case .King:
  • return "king"
  • default:
  • return String(self.toRaw())
  • }
  • }
  • }


2.Associated Value

ここから先はただの進化というレベルではないものになります。関数型プログラミング言語ではいくつか採用されている、代数的データ型に相当するものがSwiftでもサポートされています。 

  • enum Barcode {
  • case UPCA(Int, Int, Int)
  • case QRCode(String)
  • }

これは、バーコード型はUPCAという(Int, Int, Int)と紐づけられる値か、QRCodeというStringと紐づけられる値のどちらかを持つ、ということを表しています。

つまり、二つの異なる形式のバーコードであるにもかかわらず、自然に同じ型として扱うことができるのです。

これらをそれぞれの値に応じて適切に処理するためには、パターンマッチングを利用して、以下のように書きます。

  • switch productBarcode {
  • case .UPCA(let numberSystem, let identifier, let check):
  • println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
  • case .QRCode(let productCode):
  • println("QR code with value of \(productCode).")
  • }

この機能により、「何らかの処理を行って成功した場合には結果を返し、失敗した場合にはエラーを返すような関数の戻り値の型」を自然に表現することができるようになります。また、switch文に書ける際に強制的にエラー処理の分岐も書かせることになるため、エラーが起きているのにも関わらず正常系のルートを通ってしまう、と行ったバグを起こす心配がありません。

総括