見出し画像

Swiftを始めよう! - Enum と構造体

Enumとは列挙体ということで、あるものを並べて示すということです。例えば

空、海、陸

東、西、北、南

など、何か関連のあるものを並べてひとまとまりで使うときに便利です。以下は基本的なもの。

    enum CompassPoint {
        case north
        case south
        case east
        case west
    }

取り出しは

var directionToHead = CompassPoint.west


Enumで使えるデータとしてはAssociated Values と Raw Valuesを定義することができます。

Raw Values

列挙型の識別子には識別子に値を持たせることができる。これをrawValueと呼ぶ。生の値。
識別子に値を持たせるものであり、識別子を別の値で利用するための手段と思って良い。つまり、代入可能な値ではない。

https://qiita.com/MaskerDog/items/627847bacc1561ec2ed3
case ace = 1

のように代入して実際の値を入れるタイプ。

Associated Values

列挙型の識別子に関連した値(Associated Values)を持たせることもできる。
これまでのPlayingCardは内部にkindとrankをもたせた構造体で考えていたが、Associated Valuesを使うことで列挙型だけで管理することもできる。
代入ではなく、その識別子に関連した値を設定することができる

https://qiita.com/MaskerDog/items/627847bacc1561ec2ed3
case result(String, String)

のように型を示して定義するタイプ

以下例示のコードはトランプをひとまとめに""enum"で定義しています。カードをひとまとめに定義して、メソッドとして関数も定義しています。

    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"が出力されます。

case ace = 1

で定義されている"1"は"raw value"生のデータとして定義されます。

一つ定義しておくと。・・・ 以下"raw value"が定義されていませんが自動的に順番に"raw value"が与えられます。

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

two ・・・ 2
three ・・・ 3


king ・・・ 13
 のように自動で番号がつきます。

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

実行すると"3"が出ます。これを"Rank(rawValue: 1)"で実行すると"ace"が出てきます。関数"simpleDescription()"が実行されていることがわかります。

もし合致するものがない場合は"nil"となります。

"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()

switch内では".hearts"のように省略形で書くことができます。

raw valueは宣言された固定値となるが、associated valuesは関連した値を設置ができるためプロパティのように自由に変更が可能。以下associated values。

case  result(String, String)
case  failure(String)

コードの例示。

    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)")
    }

associated valuesの使い方は

  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)")
   }

出力は

"Sunrise is at 6:00 am and sunset is at 8:09 pm."

構造体

    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()
    
    print(threeOfSpadesDescription)

出力すると。

The 3 of spades

struct を使用して構造体を作成します。 構造体は、メソッドや初期化子など、クラスと同じように機能します。 構造体とクラスの最も重要な違いの 1 つは、構造体はコード内で渡されるときに常にコピーされるのに対し(値渡し)、クラスは参照によって渡されることです(参照渡し)。

RankとSuitの2つのプロパティ、メソッドを持つ構造体。

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