The Swift Programming Language をまとめるトップ
Nested Types(ネストされた型)
列挙型はクラスと構造体の機能の補足として利用する
列挙型やクラスや構造体のブレス{}
の中に定義することができる
使いこなせたら結構強力
Nested Types in Action(ネスト型の使い方)
BlackjackCardという構造体を定義する
struct BlackjackCard {
// ネストされたSuit列挙型
enum Suit: Character {
case Spades = "♠", Hearts = "♡", Diamonds = "♢", Clubs = "♣"
}
// ネストされたRank列挙型
enum Rank: Int {
case Two = 2, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King, Ace
struct Values {
let first: Int, second: Int?
}
var values: Values {
switch self {
case .Ace:
return Values(first: 1, second: 11)
case .Jack, .Queen, .King:
return Values(first: 10, second: nil)
default:
return Values(first: self.toRaw(), second: nil)
}
}
}
// BlackjackCard のプロパティとメッソド
let rank: Rank, suit: Suit
var description: String {
var output = "マークは \(suit.toRaw()),"
output += " 値は \(rank.values.first)"
if let second = rank.values.second {
output += " か \(second)"
}
return output
}
}
Suit列挙型ではカードのマークの文字値をシンボルとして定義
Rank列挙型では13のカードのランクの実数値を定義
Rankの中では更に "Values" という構造体をネストしている
Ace以外のカードは1つの値しかもっていないが、Aceだけ2つの値をもっている
その構造体のプロパティの値は2種類で
first は Int型
second は オプショナルのInt型
また、Rank内ではValuesという算出プロパティも定義してる
これはValues構造体のインスタスを返す
description でオプショナル型のsecondの値を一時的に保持し評価する"Optional Binding"を使う
そして、値があれば表示させるようにしている
BlackjackCardではカスタムイニシャライザーを定義していないので、自動的に meberwise initializer が作動している
以下の様に初期化する
let theAceOfSpades = BlackjackCard(rank: .Ace, suit: .Spades)
println("theAceOfSpades: \(theAceOfSpades.description)")
// prints "theAceOfSpades: マーク ♠, 値は 1 か 11"
RankとSuitはBlackjackCardにネストされているが、コンテキストから型を推論できるので、インスタンスの初期化の時に個別のメンバー名(.Aceと.Spades)だけを指定することによってBlackjackCard内の列挙型を参照することができる
Referring to Nested Types(ネストされた型の参照)
ネストされた型の値には以下の様にして参照できる
let heartsSymbol = BlackjackCard.Suit.Hearts.toRaw()
// heartsSymbol は "♡"