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

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

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

结果示例:

♠
♥
♦
♣

当前回答

编辑: 快速进化提案SE-0194枚举案例派生集合为这个问题提出了一个水平的解决方案。我们在Swift 4.2和更新版本中看到了它。该提案还指出了一些变通方法,这些方法与这里已经提到的一些方法类似,但可能会很有趣。

为了完整起见,我也会保留我原来的职位。


这是基于@Peymmankh的回答的另一种方法,适用于Swift 3。

public protocol EnumCollection: Hashable {}

extension EnumCollection {

public static func allValues() -> [Self] {
    typealias S = Self

    let retVal = AnySequence { () -> AnyIterator<S> in
        var raw = 0
        return AnyIterator {
            let current = withUnsafePointer(to: &raw) {
                 $0.withMemoryRebound(to: S.self, capacity: 1) { $0.pointee }
            }
            guard current.hashValue == raw else { return nil }
            raw += 1
            return current
        }
    }

    return [S](retVal)
}

其他回答

在Swift中,枚举类型可以像EnumType一样访问。案例:

let tableView = UITableView(frame: self.view. view)UITableViewStyle.Plain)

大多数情况下,只有当您有几个选项可以使用,并且确切地知道在每个选项上要做什么时,才会使用枚举类型。

在处理枚举类型时,使用for-in结构没有太大意义。

你可以这样做,例如:

func sumNumbers(numbers : Int...) -> Int {
    var sum = 0

    for number in numbers{
        sum += number
    }

    return sum
}

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

我已经在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()

在处理Swift 2.0时,以下是我的建议:

我已经将原始类型添加到Suit enum

enum Suit: Int {

然后:

struct Card {
    var rank: Rank
    var suit: Suit


    func fullDeck()-> [Card] {

        var deck = [Card]()

        for i in Rank.Ace.rawValue...Rank.King.rawValue {

            for j in Suit.Spades.rawValue...Suit.Clubs.rawValue {

                deck.append(Card(rank:Rank(rawValue: i)! , suit: Suit(rawValue: j)!))
            }
        }

        return deck
    }
}

(改进Karthik Kumar的回答)

这个解决方案是使用编译器来保证你不会错过一个case。

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

    static var enumerate: [Suit] {
        switch Suit.spades {
        // make sure the two lines are identical ^_^
        case        .spades, .hearts, .diamonds, .clubs:
            return [.spades, .hearts, .diamonds, .clubs]
        }
    }
}

我使用了下面的方法,假设我知道哪个是Rank enum中的最后一个值,所有的Rank在Ace之后都有增量值

我喜欢这种方式,因为它干净,小,容易理解

 func cardDeck() -> Card[] {
     var cards: Card[] = []
     let minRank = Rank.Ace.toRaw()
     let maxRank = Rank.King.toRaw()

     for rank in minRank...maxRank {
         if var convertedRank: Rank = Rank.fromRaw(rank) {
             cards.append(Card(rank: convertedRank, suite: Suite.Clubs))
             cards.append(Card(rank: convertedRank, suite: Suite.Diamonds))
             cards.append(Card(rank: convertedRank, suite: Suite.Hearts))
             cards.append(Card(rank: convertedRank, suite: Suite.Spades))
         }
    }

    return cards
}