20202/4 Swift Nested Types

列挙型は特定のクラスや構造体の機能をサポートする生成されます。同様に、より複雑な型の中で使用するためだけにユーティリティなクラスを定義することがあります。これを実現するためSwiftはnested typesを用意しています。本体をサポートする列挙型・クラス・構造体を本体の型の定義内に定義することができます。

ある型を別の型の入れ子(ネスト)にするには、別の型の本体内にその型の定義を記述します。

Nested Typesのアクション

sample1-1はBlackjackCard構造体を定義しています。トランプゲームのブラックジャックがモデルです。BlackjackCard構造体は二つの入れ子の列挙型SuitとRankを含んでいます。

ブラックジャックではAceのカードは1あるいは11、どちらでも評価できます。この機能はValues構造体で表現します。Values構造体はRank列挙型の中に入れ子します。

struct BlackjackCard {

    // nested Suit enumeration
    enum Suit: Character {
        case spades = "♠", hearts = "♡", diamonds = "♢", clubs = "♣"
    }

    // nested Rank enumeration
    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.rawValue, second: nil)
            }
        }
    }

    // BlackjackCard properties and methods
    let rank: Rank, suit: Suit
    var description: String {
        var output = "suit is \(suit.rawValue),"
        output += " value is \(rank.values.first)"
        if let second = rank.values.second {
            output += " or \(second)"
        }
        return output
    }
}

Suit列挙型は一般的なトランプの四つの絵柄を表現します。それぞれのケースがCharacter型のraw valueを持っています。

Rank列挙型は13の出現可能性のあるカードのランクを表現し、それぞれのカードの番号を表すInt型のraw valueを持っています。このraw valueはJack,Queen,King,Aceでは使われません。使われないが、raw value自体は

  • Jack—>11
  • Queen—>12
  • King—>13
  • Ace—>14

が自動的に割り振られている。

Rank列挙型は、自身の中にさらに入れ子でValues構造体を定義しています。この構造体で、「Aceは二つの値(1 or 11)を持ち、それ以外のカードは一つの値を持つ」という事実をカプセル化します。Values構造体は以下の二つのプロパティでその事実を表現します。

  • first,Int型
  • second,Int?型(Optional<Int>型)

列挙型Rankはvaluesというコンピューテドプロパティを持ちます。このプロパティはValues構造体のインスタンスを返します。このコンピューテドプロパティvaluesはカードのランクを把握して、そのランクに対応する新しいValues構造体のインスタンスを生成(イニシャライズ)します。

BlackjackCard構造体自体には二つのプロパティ、rankとsuitがあります。それとコンピューテドプロパティdescriptionを定義しています。カードの名前(シンボル)と値を表す説明を組み立てるためにrankとsuitの値を使用します。オプショナルバインディングを使ってvaluesのsecondプロパティがnilでない場合(aceのみ)にそれを表示するようにしています。

BlackjackCard構造体は独自のイニシャライザを定義していないので、自動的にメンバワイズイニシャライザが用意されます。新しい定数theAceOfSpadesに、新しいBlackjackCardインスタンスを生成し代入することができます。

let theAceOfSpades = BlackjackCard(rank: .ace, suit: .spades)
print("theAceOfSpades: \(theAceOfSpades.description)")
// Prints "theAceOfSpades: suit is ♠, value is 1 or 11"

 

工事中

 

参考

https://docs.swift.org/swift-book/LanguageGuide/NestedTypes.html

コメントを残す

メールアドレスが公開されることはありません。