The Swift Programming Language - Enumerations（列挙型）をまとめる


[The Swift Programming Language をまとめるトップ](http://qiita.com/kiyotaman/items/052f82e9f93590b79c64)

## Enumerations（enum列挙型）
SwiftではObjCやC言語の時よりより表現力が豊

### Enumeration Syntax（シンタックス）
ブレス内に記述する

```swift
enum SomeEnumeration {
    // 定義をここに書く
}
```

コンパスの例え

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

列挙法のメンバー値、Nort, South, East, West、を定義
**case**は新しい行の始まりを意味する

> **NOTE**
> SwiftではC言語やObjective-Cとは異なりデフォルトで整数値がセットされない
> 上記の例でいうなら、North, South, East, West にそれぞれ、0, 1, 2, 3 と定義されない
> 各々 _CompassPoint._型の明示的な独立した値として定義される

（,）カンマ区切りで一行で書く事も出来る

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

それぞれ列挙型は新しい名前を定義できる
他のSwiftで使われている方と同様に最初の一文字は大文字で書く
単数系で表記しより明白に分かる様にする

```swift
var directionToHead = CompassPoint.West
```

*directionToHead* 変数が既に _CompassPoint_ の値で初期化されている場合は推論できるようになる
_CompassPoint_ として宣言された _directionToHead_ は\.どっとシンタックスをつかって簡易的に書く事ができる

```swift
directionToHead = .East
```

_directionToHead_ の型が既知であれば、代入する値の型を省くことができる
これによってより読みやすいコードになる

### Matching Enumeration Values with a Switch Statement（Switchを使った値評価）
Switchステートメントを使ってそれぞれの値を評価することができる

```swift
directionToHead = .South
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")
}
// prints "Watch out for penguins"
```

全ての列挙型の値をカバー出来ない場合 _default_ を指定する

```swift
let somePlanet = Planet.Earth
switch somePlanet {
case .Earth:
    println("Mostly harmless")
default:
    println("Not a safe place for humans")
}
// prints "Mostly harmless"
```

### Associated Values（関連値）
関連する値を持たせる事ができる

**例えば**

```swift
var response = ServerResponse.Result("6:00 am", "8:09 pm")

response = .Error("Out of cheese.")

switch response {
case let .Result(sunrise, sunset):
    let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case .Error(let error):
    let serverResponse = "Failure... \(error)"
}
println(serverResponse)
// prints "Failure... Out of cheese."
```

_ServerResonse_ に _Reuslt_ と _Error_ を定義し、それぞれの受け取る値の型を指定
_.Result()_ にセットする値の型が違う場合エラーになる

```swift
var response = ServerResponse.Result("6:00 am", "8:09 pm")
```

変数として _response_ を定義する
この時、 _response_ の型は _enum ServerResponse_ として推論され定義される

```swift
response = .Error("Out of cheese.")
```

ここで、再度 _.Error()_ で代入して _response_ を更新する
_response_ は _Error か Result_ のどちらかしか持てない

```swift
switch response {
case let .Result(sunrise, sunset):
    let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case .Error(let error):
    let serverResponse = "Failure... \(error)"
}
````

値を展開したい時は、let or var を使を使う
enum の型の前で宣言すると全ての値を同時に定数か変数として宣言できる
```.Error(let error)``` のように個別に指定もできる

### Raw Values （直接値）
色々な方の直接値を指定する事ができる
strings, characters, integer, floating-point number が使える
ObjeCのenumに近い

**例えば**

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

このように "Associated Values" は異なり、enum型名の後に指定した型の値を前もって直接指定する
"Associated Values" は、定数や変数を生成する時に値を指定するが、 enum は定義するときに指定する

_Planet_ を直接値を指定して書き換えてみる

```swift
enum Planet: Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
```

#### toRaw()

_toRaw()_ を使って値を取得するこができる
_toRaw()_ は enum に直接指定する値の型を指定してる場合のみ使える

```swift
let earthsOrder = Planet.Earth.toRaw()
// earthsOrder は 3
```

#### fromRaw()

_fromRaw()_ でenum型を取得できる

```swift
let possiblePlanet = Planet.fromRaw(7)
// possiblePlanet は Planet.Uranus で Planet?（オプショナルになる）
```

_Planet.fromRaw()_ の値はオプショナルなので、Planetが存在しない値を渡したときに nil を返す

```swift
let positionToFind = 9
if let somePlanet = Planet.fromRaw(positionToFind) {
	switch somePlanet {
	case .Earth:
    	println("Mostly harmless")
	default:
    	println("Not a safe place for humans")
	}
} else {
    println("\(positionToFind)のPlanetは存在しません")
}
// prints "9のPlanetは存在しません"
```

### func を使って振る舞い定義

_func_ を使って振る舞いを定義できたりもする

```swift
enum Planet: Int {
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
    func 日本語() -> String {
        switch self {
        case .Mercury:
            return "水星"
        case .Venus:
            return "金星"
        case .Earth:
            return "地球"
        case .Mars:
            return "火星"
        case .Jupiter:
            return "木星"
        case .Saturn:
            return "土星"
        case .Uranus:
            return "天王星"
        case .Neptune:
            return "海王星"
            
        }
    }
}

let uranus = Planet.Uranus
let uranus説明 = uranus.日本語()
// uranus説明 は "天王星"
```