見出し画像

楽しい!Swift。 - A Swift Tour (Enumerations and Structures)

列挙型(Enumerations)と構造体(Structures)です。

列挙型(Enumerations)

列挙型はいくつかのものをまとめることができる機能を名前をつけて使いまわせるというものです。例えば"東""西""南""北"を"方位"と宣言(名前をつける)して使うことができます。

列挙型を作成するには enum を使います。クラスと同様に、列挙型もメソッド(関数)を持つことができます。以下トランプの数字についてまとめています。

  case ace = 1
  case two, three, four, five, six, seven, eight, nine, ten
  case jack, queen, king

で定義して、使い方(メソッド)を定義します。

case ace = 1

と宣言すると、その後の"two"は数字の"2"が暗黙で入ります。その後も同じように当てられます(2,3,4,5,6,7,8,9,10,11,12,13:rawValueと呼びます)。特に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.rawValue)
        }
    }

まとめて

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.rawValue)
        }
    }
}

使うときは

let ace = Rank.ace
let aceRawValue = ace.rawValue

print(aceRawValue)

とすると"1"が出てきます。

イニシャライザを使用して、rawValueから列挙型を使います。 rawValueに一致する場合は該当の列挙型ケースを返します。一致するRankがない場合は nil を返します。

if let convertedRank = Rank(rawValue: 3) {
    let threeDescription = convertedRank.simpleDescription()
}

この場合必要なのは実在の値です。、raw value の値を表す他の方法を示すものではありません。実際、raw value が存在しない場合は、raw value は必要ないからです。

enum Suit {
    case spades, hearts, diamonds, clubs


    func simpleDescription() -> String {
        switch self {
        case .spades:
            return "spades"
        case .hearts:
            return "hearts"
        case .diamonds:
            return "diamonds"
        case .clubs:
            return "clubs"
        }
    }
}
let hearts = Suit.hearts
let heartsDescription = hearts.simpleDescription()

上記では2つの"case"の使い方を紹介しています。

enumで直接caseで参照するときは"Suits.hearts"という書き方で表すことができます。一方switch文の中では" .hearts"と省略記法が使われています。

列挙型が raw value を持つ場合、値は宣言の一部として決定されます。特定のcaseのは、必ず同じ raw value を持ちます。

raw valueの他に、Associated value(関連値)を持つcaseを作ることができます。Associated valueは使う時に決定され、使う時ごとに異なる値を持つことができます。Associated valueはstored propertyのように使うことができます。

以下は、サーバから日の出時刻と日の入り時刻をリクエストする場合です。サーバはリクエスト情報に応じたレスポンスを返すか、リクエストが間違っている場合は間違っているという内容を返します。

enum ServerResponse {
    case result(String, String)
    case failure(String)
}


let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")


switch success {
case let .result(sunrise, sunset):
    print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
    print("Failure...  \(message)")
}
// Prints "Sunrise is at 6:00 am and sunset is at 8:09 pm."

日の出時刻と日の入り時刻が、switch に合致したケースの一部として、ServerResponse から抽出されています。

構造体を作成するには struct を使います。構造体はメソッドやイニシャライザなど多くのクラスと同じように使うことができます。

最も重要な違いは、構造体は渡される時に必ずコピーされる値型。値型を作った場合は他のインスタンスを変更しても影響はありません。クラスは参照を渡す参照型なのでその値を変更すると他のものも変更されます(値は他のものに参照されている)。

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}

使うときは

let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

この記事が気に入ったらサポートをしてみませんか?