How to compare enum with associated values by ignoring its associated value in Swift?

匿名 (未验证) 提交于 2019-12-03 01:38:01

问题:

After reading How to test equality of Swift enums with associated values, I implemented the following 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     } } 

The following code works:

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.") } 

However, this doesn't compile:

let number = CardRank.Number(5) if number == CardRank.Number {     print("You must play a face card!") } 

... and it gives the following error message:

Binary operator '==' cannot be applied to operands of type 'CardRank' and '(Int) -> CardRank'

I'm assuming this is because it's expecting a full type and CardRank.Number does not specify an entire type, whereas CardRank.Number(2) did. However, in this case, I want it to match any number; not just a specific one.

Obviously I can use a switch statement, but the whole point of implementing the == operator was to avoid this verbose solution:

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

Is there any way to compare an enum with associated values while ignoring its associated value?

Note: I realize that I could change the case in the == method to case (.Number, .Number): return true, but, although it would return true correctly, my comparison would still look like its being compared to a specific number (number == CardRank.Number(2); where 2 is a dummy value) rather than any number (number == CardRank.Number).

回答1:

Edit: As Etan points out, you can omit the (_) wildcard match to use this more cleanly.


Unfortunately, I don't believe that there's an easier way than your switch approach in Swift 1.2.

In Swift 2, however, you can use the new if-case pattern match:

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

If you're looking to avoid verbosity, you might consider adding an isNumber computed property to your enum that implements your switch statement.



回答2:

Unfortunately in Swift 1.x there isn't another way so you have to use switch which isn't as elegant as Swift 2's version where you can use if case:

if case .Number = number {     //ignore the value } if case .Number(let x) = number {     //without ignoring } 


回答3:

Here's a simpler approach:

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)     } } 

There's no need to overload the == operator, and checking for card type does not require confusing 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!") } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!