列挙型

列挙型の基本
共用体な列挙型
なまの値を持つ列挙型
Intな列挙型

列挙型の基本

列挙型は次のように宣言する。

/*
enum なまえ {
	列挙列挙
}
*/

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

enumの名前は大文字で始めること。
あと、swiftの列挙型は基本的には数字の番号が列挙した要素にふられないので注意。このあたりCとかとは違う。っていうかCにenumあったのな。
caseを書くのが面倒なので1行でまとめてもOK。

enum Planet {
	case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

使う時は「enumのなまえ.使いたい要素」って感じで。以下のdirectionToHeadのように、1度代入して型が決まっているような場合は型を察してくれるのでenumのなまえを省略可能。

var directionToHead = CompassPoint.West	//CompassPoint型の変数

directionToHead = .East	//型が分かっているならドット以降だけで足りる

switch文でenumを扱う場合、switch ~のところで型を察することができるので、以下のようにやはりcaseのところでenumの名前を省略できる。

directionToHead = .South

//Watch out for penguins
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")
}

//defaultを使ったパターン
//Mostly harmless
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
	println("Mostly harmless")
default:
	println("Not a safe place for humans")
}

共用体な列挙型

原文ではassociated valuesという。訳として共用体が正しいのかはわからない。
先ほどまでの例は「South」だの「Earth」だのといった単品だけだったが、付属品として別の値も覚えさせることができる。
次の例ではBarcodeの中にUPCAとQRCodeが列挙されているが、それぞれ数字や文字列を持つことができるようになっている。ちなみにUPCAはレジでピッするようなバーコード。

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

Barcodeは2つのコードを列挙していて、それぞれがコードで表現したい情報を持てるようになっている……と表現すればいいんだろうか。
実際にBarcodeを使うと次のような感じ。productBarcodeにtuple(8, 8590951226, 3)を持ったUPCAが入る。で、1度Barcode型のものを入れてBarcode型であることが分かっているので、その後の代入ではBarcodeが省略できる。

var productBarcode = Barcode.UPCA(8, 85909_51226, 3)	//アンダーバーは可読性を持たせるだけのもの
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

例によってcase文の中でletとかvarとかやると値を取り出せるので、switch文の中でいろいろな処理ができる。

//QR code with value of ABCDEFGHIJKLMNOP
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).")
}

上の例ではちまちまlet, let, ...とやっていたが、カッコの中全部がletとかvarなのであれば外側にletやvarをつけて1度で済ましてもいい。

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

なまの値を持つ列挙型

rawってなまっていう訳しか知らないんだけど。
ここまで共用体として値がセットになった要素を見てきたが、似たような機能にRaw Valuesというのもあり、要素が自身型をもって値を持つことができる。
上の共用体と違うのは、列挙型を定義するときに決める値であることと、その列挙型で値が共通であるということ。(共用体はインスタンスごとに違う値が取れる)

enum ASCIIControlCharacter: Character {
	case Tab = "\t"
	case LineFeed = "\n"
	case CarriageReturn = "\r"
}

使える方はCharacterのほか、String、Int、Float。いずれにしても同じ値を入れてはいけないというか、Raw Valuesはユニークでなければならない。
Int型の場合、特に決まっていなければ先頭から順番に数字が入れられる。

enum Planet: Int {
	//1からスタート(と書かないと0から番号が振られる)
	case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

ここで、Earthは3、7はUranusという対応関係が生まれるので、toRawやfromRawで変換ができる。

let earthsOrder = Planet.Earth.toRaw()	//3が得られる
let possiblePlanet = Planet.fromRaw(7)	//Planet.Uranusが得られる

なお、fromRawに存在しない番号を与える(たとえばfromRaw(9)とか)と、nilが返ってくる。つまりpossiblePlanetはPlanet?型の変数である。

let positionToFind = 9

//There isn't a planet at position 9
if let somePlanet = Planet.fromRaw(positionToFind) {
	switch somePlanet {
	case .Earth:
		println("Mostly harmless")
	default:
		println("Not a safe place for humans")
	}
} else {
	println("There isn't a planet at position \(positionToFind)")
}

↑ PAGE TOP