the - ¿Cómo comparar enum con valores asociados al ignorar su valor asociado en Swift?
swift 4 enum string (4)
Aquí hay un enfoque más 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)
}
}
No es necesario sobrecargar el operador ==, y verificar el tipo de tarjeta no requiere una sintaxis confusa:
let card = CardRank.Jack
if card == CardRank.Jack {
print("You played a jack")
} else if !card.isFaceCard {
print("You must play a face card!")
}
Después de leer Cómo probar la igualdad de enumeraciones Swift con valores asociados , implementé la siguiente enumeración:
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
}
}
El siguiente código funciona:
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.")
}
Sin embargo, esto no compila:
let number = CardRank.Number(5)
if number == CardRank.Number {
print("You must play a face card!")
}
... y da el siguiente mensaje de error:
El operador binario ''=='' no se puede aplicar a operandos de tipo ''CardRank'' y ''(Int) -> CardRank''
Supongo que esto se debe a que espera un tipo completo y
CardRank.Number
no especifica un tipo completo, mientras que
CardRank.Number(2)
sí lo hizo.
Sin embargo, en este caso, quiero que coincida con
cualquier
número;
no solo uno específico.
Obviamente, puedo usar una instrucción switch, pero el objetivo de implementar el operador
==
era evitar esta solución detallada:
switch number {
case .Number:
print("You must play a face card!")
default:
break
}
¿Hay alguna manera de comparar una enumeración con valores asociados mientras se ignora su valor asociado?
Nota:
Me doy cuenta de que podría cambiar el caso en el método
==
a
case (.Number, .Number): return true
, pero, aunque devolvería true correctamente, mi comparación aún parecería que se compara con un número específico (
number == CardRank.Number(2)
; donde 2 es un valor ficticio) en lugar de
cualquier
número (
number == CardRank.Number
).
Desafortunadamente, en Swift 1.x no hay otra manera, por lo que debe usar el
switch
que no es tan elegante como la versión de Swift 2, donde puede usar
if case
:
if case .Number = number {
//ignore the value
}
if case .Number(let x) = number {
//without ignoring
}
En Swift 4.2
Equatable
se sintetizará si todos sus valores asociados se ajustan a
Equatable
.
Todo lo que necesitas hacer es agregar
Equatable
.
enum CardRank: Equatable {
case Number(Int)
case Jack
case Queen
case King
case Ace
}
https://developer.apple.com/documentation/swift/equatable?changes=_3
Editar:
como señala Etan, puede omitir la coincidencia de comodines
(_)
para usar esto de manera más limpia.
Desafortunadamente, no creo que haya una forma más fácil que su enfoque de
switch
en Swift 1.2.
En Swift 2, sin embargo, puede usar la nueva coincidencia de patrón
if-case
:
let number = CardRank.Number(5)
if case .Number(_) = number {
// Is a number
} else {
// Something else
}
Si está buscando evitar la verbosidad, podría considerar agregar una propiedad calculada
isNumber
a su enumeración que implemente su instrucción switch.