extension - swift enum 呼び出し




Swiftで関連付けられた値を無視して、列挙値を関連付けられた値と比較する方法は? (3)

Swift 4.2 Equatable 、関連するすべての値が Equatable 適合する場合、 Equatable が合成されます。 Equatable 追加する Equatable です。

enum CardRank: Equatable {
    case Number(Int)
    case Jack
    case Queen
    case King
    case Ace
}

https://developer.apple.com/documentation/swift/equatable?changes=_3

関連する値を持つSwift列挙型の等価性をテストする方法を 読んだ後、次の列挙型を実装しました。

enum CardRank {
    case Number(Int)
    case Jack
    case Queen
    case King
    case Ace
}

func ==(a: CardRank, b: CardRank) -> Bool {
    switch (a, b) {
    case (.Number(let a), .Number(let b))   where a == b: return true
    case (.Jack, .Jack): return true
    case (.Queen, .Queen): return true
    case (.King, .King): return true
    case (.Ace, .Ace): return true
    default: return false
    }
}

次のコードが機能します。

let card: CardRank = CardRank.Jack
if card == CardRank.Jack {
    print("You played a jack!")
} else if card == CardRank.Number(2) {
    print("A two cannot be played at this time.")
}

ただし、これはコンパイルされません。

let number = CardRank.Number(5)
if number == CardRank.Number {
    print("You must play a face card!")
}

...そして、次のエラーメッセージが表示されます。

二項演算子「==」は、タイプ「CardRank」および「(Int)-> CardRank」のオペランドには適用できません

これは、完全なタイプを想定しているためであり、 CardRank.Number(2) が指定したのに対し、 CardRank.Number(2) タイプ全体を指定しないためです。 ただし、この場合、 任意の 番号と一致させたい。 特定のものだけではありません。

明らかにswitchステートメントを使用できますが、 == 演算子を実装する全体のポイントは、この冗長なソリューションを回避することでした。

switch number {
case .Number:
    print("You must play a face card!")
default:
    break
}

関連付けられた値を無視しながら、列挙値を関連付けられた値と比較する方法はありますか?

注: == メソッドの case (.Number, .Number): return truecase (.Number, .Number): return true 変更できることを理解してい case (.Number, .Number): return true が、trueを正しく返しますが、比較は特定の番号と比較されているように見えます( number == CardRank.Number(2) ;ここで2はダミー値です) 任意の 数字( number == CardRank.Number )ではあり ません


より簡単なアプローチを次に示します。

enum CardRank {
    case Two
    case Three
    case Four
    case Five
    case Six
    case Seven
    case Eight
    case Nine
    case Ten
    case Jack
    case Queen
    case King
    case Ace

    var isFaceCard: Bool {
        return (self == Jack) || (self == Queen) || (self == King)
    }
}

==演算子をオーバーロードする必要はありません。また、カードの種類を確認するために、複雑な構文は必要ありません。

let card = CardRank.Jack

if card == CardRank.Jack {
    print("You played a jack")
} else if !card.isFaceCard {
    print("You must play a face card!")
}

編集: Etanが指摘しているように、 (_) ワイルドカードの一致を省略して、これをよりきれいに使用できます。

残念ながら、Swift 1.2での switch アプローチよりも簡単な方法があるとは思わない。

ただし、Swift 2では、新しい if-case パターンマッチを使用できます。

let number = CardRank.Number(5)
if case .Number(_) = number {
    // Is a number
} else {
    // Something else
}

冗長性を避けたい場合は、switchステートメントを実装する列挙に isNumber 計算プロパティを追加することを検討してください。





comparison