1. ホーム
  2. swift

[解決済み] Swiftでenumの関連値を無視して比較する方法は?

2022-10-25 17:18:42

質問

読後感 関連する値を持つ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 は型全体を指定しないのに対し CardRank.Number(2) がそうであったのに対して。しかし、この場合、私はそれが にも 番号にマッチさせたいのです。

もちろんswitchステートメントを使うことも出来ますが、このように == 演算子を実装したのは、この冗長な解決策を回避するためです。

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

enumの関連値を無視して、関連値と比較する方法はありますか?

注意してください。 の大文字と小文字を変更できることに気づきました。 == メソッドを case (.Number, .Number): return true というメソッドがありますが、これは正しく真を返しますが、私の比較はまだ特定の数字と比較されているように見えます ( number == CardRank.Number(2) ここで 2 はダミー値です)ではなく 任意 の数でなく ( number == CardRank.Number ).

どのように解決するのですか?

編集してください。 Etan が指摘するように (_) のワイルドカードマッチを省略することができます。


残念ながら、私はあなたの switch のアプローチよりも簡単な方法はないと思います。

しかし、Swift 2 では、新しい if-case のパターンマッチを使うことができます。

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

冗長性を避けたいのであれば、冗長性をなくすために isNumber を追加して、switch ステートメントを実装することができます。