Depois de ler Como testar a igualdade de enums do Swift com valores associados , implementei o seguinte enum:
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
}
}
O seguinte 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.")
}
No entanto, isso não compila:
let number = CardRank.Number(5)
if number == CardRank.Number {
print("You must play a face card!")
}
... e dá a seguinte mensagem de erro:
O operador binário '==' não pode ser aplicado a operandos do tipo 'CardRank' e '(Int) -> CardRank'
Estou supondo que isso ocorre porque ele está esperando um tipo completo e CardRank.Number
não especifica um tipo inteiro, enquanto o CardRank.Number(2)
fazia. No entanto, neste caso, quero que corresponda a qualquer número; não apenas um específico.
Obviamente, posso usar uma instrução switch, mas o objetivo principal da implementação do ==
operador era evitar esta solução detalhada:
switch number {
case .Number:
print("You must play a face card!")
default:
break
}
Existe alguma maneira de comparar um enum com valores associados enquanto ignora seu valor associado?
Observação: eu percebo que poderia alterar o caso no ==
método para case (.Number, .Number): return true
, mas, embora retornasse verdadeiro corretamente, minha comparação ainda pareceria estar sendo comparada a um número específico ( number == CardRank.Number(2)
; onde 2 é um valor fictício) em vez de qualquer número ( number == CardRank.Number
).
fonte
Jack
,Queen
,King
,Ace
casos na==
implementação operador apenas:case (let x, let y) where x == y: return true
Respostas:
Edit: Como Etan aponta, você pode omitir a
(_)
correspondência curinga para usar isso de forma mais limpa.Infelizmente, não acredito que haja uma maneira mais fácil do que sua
switch
abordagem no Swift 1.2.No Swift 2, no entanto, você pode usar a nova
if-case
correspondência de padrão:let number = CardRank.Number(5) if case .Number(_) = number { // Is a number } else { // Something else }
Se você está procurando evitar o detalhamento, pode considerar adicionar uma
isNumber
propriedade computada ao seu enum que implemente sua instrução switch.fonte
assert(number == .Number)
. Só posso esperar que isso seja melhorado nas versões posteriores do Swift. = /default
recorrer a um caso em umswitch
bloco por enquanto.Infelizmente, no Swift 1.x não há outra maneira de usar
switch
que não seja tão elegante quanto a versão do Swift 2, onde você pode usarif case
:if case .Number = number { //ignore the value } if case .Number(let x) = number { //without ignoring }
fonte
if
declarações, não como uma expressão.No Swift 4.2
Equatable
será sintetizado se todos os seus valores associados estiverem em conformidadeEquatable
. Tudo que você precisa fazer é adicionarEquatable
.enum CardRank: Equatable { case Number(Int) case Jack case Queen case King case Ace }
https://developer.apple.com/documentation/swift/equatable?changes=_3
fonte
Esta é uma abordagem mais simples:
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) } }
Não há necessidade de sobrecarregar o operador == e a verificação do tipo de cartão não requer sintaxe 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!") }
fonte
Você não precisa
func ==
ouEquatable
. Basta usar um padrão de caso de enumeração .let rank = CardRank.Ace if case .Ace = rank { print("Snoopy") }
fonte