Après avoir lu Comment tester l'égalité des énumérations Swift avec les valeurs associées , j'ai implémenté l'énumération suivante:
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
}
}
Le code suivant fonctionne:
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.")
}
Cependant, cela ne compile pas:
let number = CardRank.Number(5)
if number == CardRank.Number {
print("You must play a face card!")
}
... et il donne le message d'erreur suivant:
L'opérateur binaire '==' ne peut pas être appliqué aux opérandes de type 'CardRank' et '(Int) -> CardRank'
Je suppose que c'est parce qu'il attend un type complet et CardRank.Number
ne spécifie pas un type entier, alors qu'il l'a CardRank.Number(2)
fait. Cependant, dans ce cas, je veux qu'il corresponde à n'importe quel nombre; pas seulement un spécifique.
Évidemment, je peux utiliser une instruction switch, mais le but de l'implémentation de l' ==
opérateur était d'éviter cette solution verbeuse:
switch number {
case .Number:
print("You must play a face card!")
default:
break
}
Existe-t-il un moyen de comparer une énumération avec les valeurs associées tout en ignorant sa valeur associée?
Remarque: je me rends compte que je pourrais changer la casse de la ==
méthode en case (.Number, .Number): return true
, mais, même si elle retournerait vrai correctement, ma comparaison ressemblerait toujours à un nombre spécifique ( number == CardRank.Number(2)
; où 2 est une valeur fictive) plutôt qu'à n'importe quel nombre ( number == CardRank.Number
).
la source
Jack
,Queen
,King
,Ace
cas dans la==
mise en œuvre de l' opérateur juste:case (let x, let y) where x == y: return true
Réponses:
Edit: Comme le souligne Etan, vous pouvez omettre la
(_)
correspondance générique pour l'utiliser plus proprement.Malheureusement, je ne pense pas qu'il existe un moyen plus simple que votre
switch
approche dans Swift 1.2.Dans Swift 2, cependant, vous pouvez utiliser la nouvelle
if-case
correspondance de modèle:let number = CardRank.Number(5) if case .Number(_) = number { // Is a number } else { // Something else }
Si vous cherchez à éviter la verbosité, vous pouvez envisager d'ajouter une
isNumber
propriété calculée à votre énumération qui implémente votre instruction switch.la source
assert(number == .Number)
. Je ne peux qu'espérer que cela sera amélioré dans les versions ultérieures de Swift. = /default
affaire dans unswitch
bloc pour le moment.Malheureusement, dans Swift 1.x, il n'y a pas d'autre moyen, vous devez donc utiliser
switch
ce qui n'est pas aussi élégant que la version de Swift 2 où vous pouvez utiliserif case
:if case .Number = number { //ignore the value } if case .Number(let x) = number { //without ignoring }
la source
if
déclarations, pas comme une expression.Dans Swift 4.2
Equatable
sera synthétisé si toutes vos valeurs associées sont conformes àEquatable
. Tout ce que vous avez à faire est d'ajouterEquatable
.enum CardRank: Equatable { case Number(Int) case Jack case Queen case King case Ace }
https://developer.apple.com/documentation/swift/equatable?changes=_3
la source
Voici une approche plus simple:
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) } }
Il n'est pas nécessaire de surcharger l'opérateur ==, et la vérification du type de carte ne nécessite pas de syntaxe déroutante:
let card = CardRank.Jack if card == CardRank.Jack { print("You played a jack") } else if !card.isFaceCard { print("You must play a face card!") }
la source
Vous n'avez pas besoin de
func ==
ouEquatable
. Utilisez simplement un modèle de cas d'énumération .let rank = CardRank.Ace if case .Ace = rank { print("Snoopy") }
la source