Nachdem ich gelesen habe, wie man die Gleichheit von Swift-Aufzählungen mit zugehörigen Werten testet , habe ich die folgende Aufzählung implementiert:
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
}
}
Der folgende Code funktioniert:
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.")
}
Dies wird jedoch nicht kompiliert:
let number = CardRank.Number(5)
if number == CardRank.Number {
print("You must play a face card!")
}
... und es wird folgende Fehlermeldung angezeigt:
Der Binäroperator '==' kann nicht auf Operanden vom Typ 'CardRank' und '(Int) -> CardRank' angewendet werden.
Ich gehe davon aus, dass dies daran liegt, dass ein vollständiger Typ erwartet wird und CardRank.Number
nicht der gesamte Typ angegeben wird, wohingegen CardRank.Number(2)
dies der Fall ist . In diesem Fall möchte ich jedoch, dass es mit einer beliebigen Zahl übereinstimmt . nicht nur eine bestimmte.
Natürlich kann ich eine switch-Anweisung verwenden, aber der Sinn der Implementierung des ==
Operators bestand darin, diese ausführliche Lösung zu vermeiden:
switch number {
case .Number:
print("You must play a face card!")
default:
break
}
Gibt es eine Möglichkeit, eine Aufzählung mit zugeordneten Werten zu vergleichen, während der zugehörige Wert ignoriert wird?
Hinweis: Mir ist klar, dass ich den Fall in der ==
Methode in ändern könnte case (.Number, .Number): return true
, aber obwohl er korrekt zurückgegeben wird, sieht mein Vergleich immer noch so aus, als würde er mit einer bestimmten Zahl ( number == CardRank.Number(2)
wobei 2 ein Dummy-Wert ist) und nicht mit einer beliebigen Zahl verglichen ( number == CardRank.Number
).
quelle
Jack
,Queen
,King
,Ace
Fälle in der==
Operatorimplementierung nur:case (let x, let y) where x == y: return true
Antworten:
Bearbeiten: Wie Etan betont, können Sie die
(_)
Platzhalterübereinstimmung weglassen , um diese sauberer zu verwenden.Leider glaube ich nicht, dass es
switch
in Swift 1.2 einen einfacheren Weg gibt als Ihren Ansatz.In Swift 2 können Sie jedoch die neue
if-case
Musterübereinstimmung verwenden:let number = CardRank.Number(5) if case .Number(_) = number { // Is a number } else { // Something else }
Wenn Sie Ausführlichkeit vermeiden möchten, können Sie
isNumber
Ihrer Aufzählung eine berechnete Eigenschaft hinzufügen , die Ihre switch-Anweisung implementiert.quelle
assert(number == .Number)
. Ich kann nur hoffen, dass dies in späteren Versionen von Swift verbessert wird. = /default
Fall in einemswitch
Block zurückgreifen .Leider gibt es in Swift 1.x keinen anderen Weg, den Sie verwenden müssen,
switch
der nicht so elegant ist wie die Version von Swift 2, in der Sie Folgendes verwenden könnenif case
:if case .Number = number { //ignore the value } if case .Number(let x) = number { //without ignoring }
quelle
if
Aussagen, nicht als Ausdruck.In Swift wird 4.2
Equatable
synthetisiert, wenn alle zugehörigen Werte übereinstimmenEquatable
. Alles was Sie tun müssen, ist hinzufügenEquatable
.enum CardRank: Equatable { case Number(Int) case Jack case Queen case King case Ace }
https://developer.apple.com/documentation/swift/equatable?changes=_3
quelle
Hier ist ein einfacherer Ansatz:
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) } }
Der Operator == muss nicht überladen werden, und die Überprüfung des Kartentyps erfordert keine verwirrende Syntax:
let card = CardRank.Jack if card == CardRank.Jack { print("You played a jack") } else if !card.isFaceCard { print("You must play a face card!") }
quelle
Du brauchst nicht
func ==
oderEquatable
. Verwenden Sie einfach ein Aufzählungsmuster .let rank = CardRank.Ace if case .Ace = rank { print("Snoopy") }
quelle