将 Switch 语句与带有嵌套枚举的结构一起使用 - Swift

Using Switch Statement with Struct with Nested Enum - Swift

带嵌套枚举结构的 Switch 语句

Swift4.1,Xcode9.3.1

我有一个非常具体的案例需要满足,但我在编写它时遇到了问题(下面有更多信息)

***查看countHand(_:)

中的评论

我的代码:

enum Suit {
    case Clubs, Diamonds, Hearts, Spades
}

enum Rank {
    case Jack, Queen, King, Ace
    case Num(Int)
}

struct Card {
    let suit: Suit
    let rank: Rank
}

extension Rank: Equatable {
    static func == (lhs: Rank, rhs: Rank)
        -> Bool {
        switch (lhs, rhs) {
        case (.Jack, .Jack), (.Queen, .Queen), (.King, .King), (.Ace, .Ace):
            return true
        case let (.Num(n1), .Num(n2)) where n1 == n2:
            return true
        default:
            return false
        }
    }
}

extension Suit: Equatable {
    static func == (lhs: Suit, rhs: Suit)
        -> Bool {
        switch (lhs, rhs) {
        case (.Diamonds, .Diamonds), (.Hearts, .Hearts), (.Spades, .Spades), (.Clubs, .Clubs):
            return true
        default:
            return false
        }
    }
}


//Main Function
func countHand(_ cards: [Card]) -> Int {

    var count = 0

    zip(cards, cards[1...]).forEach { card, nextCard in
        let bothCards = (card, nextCard)

        switch bothCards {
        case let (c1, c2) where c1.rank == .Num(5) && c1.suit == .Diamonds && c2.rank == .Ace:
            count += 100

        case let (c1, c2) where c1.suit == .Hearts && ![.Jack, .Queen, .King, .Ace].contains(c2.rank): //I checked the contents of the array as a workaround to determine that the rank is a numeric value 

            //Also, if c2.rank is Rank.Num(let n) where n == 3 || n == 5 || n == 7 || n == 9

            count += n * 2

        default:
            break
        }

    }

    return count


}

卡片价值

卡值如下:


要求

我想做的是 - 关于我的第二个案例陈述 - 我只想在第一张卡片 c1 和第二张卡片 c2 时调用它,满足这些标准:

  1. c1.suit.Hearts

  2. c2.rank 是数字 (.Num(n)) 而 n 是 3、5、7 或 9

如果这两个条件都满足,我想将 count 的值增加到 n * 2


我的问题

我进行了深入搜索,试图在网上找到一个与我的相似的案例,但不幸的是,有 none - 我可以找到 - 与我正在寻找的特异性水平相匹配为.

我试图通过做 where ... && c2.rank = .Num(let n) 之类的事情将它添加到 where 谓词中,在案例中写了一个 if 语句,只更改 [=20] 的值=] 如果它是 3、5、7 或 9,但这会产生各种错误,但我认为这不是实现它的最佳方法。这是我要解决的主要问题。如果我能做到这一点,我很确定我可以解决 where ... && ![.Jack, .Queen, .King, .Ace].contains(c2.rank).


提前感谢大家的所有建议、解决方案、反馈等,非常感谢您的帮助!

您不能在 where 子句中进行模式匹配,但是 您可以改为打开两张卡的两个属性:

switch (card.suit, card.rank, nextCard.suit, nextCard.rank) {
case (.Diamonds, .Num(5), _, .Ace):
    count += 100
case (.Hearts, _, _, .Num(let n)) where n >= 3 && n % 2 != 0:
    // Or: ... where [3, 5, 7, 9].contains(n):
    count += n * 2
default:
    break
}

备注:根据目前的Swift API Design Guidelines,枚举属性应该是小写的:

Names of types and protocols are UpperCamelCase. Everything else is lowerCamelCase.