enum Suit: String {
    case spades = "♠"
    case hearts = "♥"
    case diamonds = "♦"
    case clubs = "♣"
}

例如,我怎么做这样的事情:

for suit in Suit {
    // do something with suit
    print(suit.rawValue)
}

结果示例:

♠
♥
♦
♣

当前回答

其他的解决方法都是可行的,但它们都假设了可能的等级和花色的数量,或者第一和最后的等级是什么。的确,在可预见的未来,一副纸牌的布局可能不会有太大变化。然而,一般来说,编写尽可能少假设的代码会更简洁。我的解决方案:

我已经在Suit枚举中添加了一个原始类型,所以我可以使用Suit(rawValue:)来访问Suit案例:

enum Suit: Int {
    case Spades = 1
    case Hearts, Diamonds, Clubs
    func simpleDescription() -> String {
        switch self {
            case .Spades:
                return "spades"
            case .Hearts:
                return "hearts"
            case .Diamonds:
                return "diamonds"
            case .Clubs:
                return "clubs"
        }
    }
    func color() -> String {
        switch self {
        case .Spades:
            return "black"
        case .Clubs:
            return "black"
        case .Diamonds:
            return "red"
        case .Hearts:
            return "red"
        }
    }
}

enum Rank: Int {
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
            case .Ace:
                return "ace"
            case .Jack:
                return "jack"
            case .Queen:
                return "queen"
            case .King:
                return "king"
            default:
                return String(self.rawValue)
        }
    }
}

在Card的createDeck()方法实现的下面。init(rawValue:)是一个可失败的初始化式,返回一个可选值。通过在两个while语句中展开并检查它的值,不需要假设Rank或Suit情况的数量:

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
    func createDeck() -> [Card] {
        var n = 1
        var deck = [Card]()
        while let rank = Rank(rawValue: n) {
            var m = 1
            while let suit = Suit(rawValue: m) {
                deck.append(Card(rank: rank, suit: suit))
                m += 1
            }
            n += 1
        }
        return deck
    }
}

下面是如何调用createDeck方法:

let card = Card(rank: Rank.Ace, suit: Suit.Clubs)
let deck = card.createDeck()

其他回答

你可以试着像这样列举

enum Planet: String {
    case Mercury
    case Venus
    case Earth
    case Mars

    static var enumerate: [Planet] {
        var a: [Planet] = []
        switch Planet.Mercury {
            case .Mercury: a.append(.Mercury); fallthrough
            case .Venus: a.append(.Venus); fallthrough
            case .Earth: a.append(.Earth); fallthrough
            case .Mars: a.append(.Mars)
        }
    return a
    }
}

Planet.enumerate // [Mercury, Venus, Earth, Mars]

如果您仍然想为Rank和Suit使用枚举,这里有一个不那么神秘的例子。如果您想使用for-in循环遍历每个对象,只需将它们收集到一个Array中。

标准52张牌的例子:

enum Rank: Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
    func name() -> String {
        switch self {
        case .Ace:
            return "ace"
        case .Jack:
            return "jack"
        case .Queen:
            return "queen"
        case .King:
            return "king"
        default:
            return String(self.toRaw())
        }
    }
}

enum Suit: Int {
    case Diamonds = 1, Clubs, Hearts, Spades
    func name() -> String {
        switch self {
        case .Diamonds:
            return "diamonds"
        case .Clubs:
            return "clubs"
        case .Hearts:
            return "hearts"
        case .Spades:
            return "spades"
        default:
            return "NOT A VALID SUIT"
        }
    }
}

let Ranks = [
    Rank.Ace,
    Rank.Two,
    Rank.Three,
    Rank.Four,
    Rank.Five,
    Rank.Six,
    Rank.Seven,
    Rank.Eight,
    Rank.Nine,
    Rank.Ten,
    Rank.Jack,
    Rank.Queen,
    Rank.King
]

let Suits = [
    Suit.Diamonds,
    Suit.Clubs,
    Suit.Hearts,
    Suit.Spades
]


class Card {
    var rank: Rank
    var suit: Suit

    init(rank: Rank, suit: Suit) {
        self.rank = rank
        self.suit = suit
    }
}

class Deck {
    var cards = Card[]()

    init() {
        for rank in Ranks {
            for suit in Suits {
                cards.append(Card(rank: rank, suit: suit))
            }
        }
    }
}

var myDeck = Deck()
myDeck.cards.count  // => 52
enum Rank: Int {
    ...
    static let ranks = (Rank.Ace.rawValue ... Rank.King.rawValue).map{Rank(rawValue: $0)! }

}
enum Suit {
    ...
    static let suits = [Spades, Hearts, Diamonds, Clubs]
}

struct Card {
    ...
    static func fullDesk() -> [Card] {
        var desk: [Card] = []
        for suit in Suit.suits {
            for rank in Rank.ranks {
                desk.append(Card(rank: rank,suit: suit))
            }
        }
        return desk
    }
}

这个怎么样?

有一种聪明的方法,尽管令人沮丧,但它说明了两种不同类型的枚举之间的区别。

试试这个:

    func makeDeck() -> Card[] {
      var deck: Card[] = []
      var suits: Suit[] = [.Hearts, .Diamonds, .Clubs, .Spades]
      for i in 1...13 {
        for suit in suits {
          deck += Card(rank: Rank.fromRaw(i)!, suit: suit)
        }
      }
      return deck
    }

交易是,一个由数字(原始值)支持的枚举是隐式显式有序的,而一个没有数字支持的枚举是显式隐式无序的。

例如,当我们给枚举值数字时,语言足够狡猾,可以找出数字的顺序。 另一方面,如果我们不给它任何顺序,当我们尝试迭代这些值时,语言就会举起双手说:“是的,但你想先执行哪个??”

其他可以做到这一点(迭代无序枚举)的语言可能是相同的语言,其中所有内容实际上都是一个地图或字典,你可以迭代地图的键,无论是否有任何逻辑顺序。

诀窍是给它提供一些显式排序的东西,在这个例子中,suit的实例在数组中按照我们想要的顺序。一旦你这么说,霉霉就会说“你为什么不一开始就这么说呢?”

另一个简写技巧是在fromRaw函数上使用强制操作符。这说明了关于枚举的另一个“陷阱”,即可能传入的值的范围通常大于枚举的范围。例如,如果我们说Rank.fromRaw(60),就不会返回值,所以我们使用了语言的可选特性,在我们开始使用可选特性的地方,很快就会出现强制。(或者交替if let结构,这对我来说仍然有点奇怪)

实验内容是: 实验

在Card中添加一个方法,用于创建一副完整的牌,每一副牌都是rank和花色的组合。

因此,除了添加方法之外,没有修改或增强给定的代码(并且没有使用还没有教过的东西),我想出了这个解决方案:

struct Card {
    var rank: Rank
    var suit: Suit

    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }

    func createDeck() -> [Card] {
        var deck: [Card] = []
        for rank in Rank.Ace.rawValue...Rank.King.rawValue {
            for suit in Suit.Spades.rawValue...Suit.Clubs.rawValue {
                let card = Card(rank: Rank(rawValue: rank)!, suit: Suit(rawValue: suit)!)
                //println(card.simpleDescription())
                deck += [card]
            }
        }
        return deck
    }
}
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
let deck = threeOfSpades.createDeck()