enum Suit: String {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
}
例如,我怎么做这样的事情:
for suit in Suit {
// do something with suit
print(suit.rawValue)
}
结果示例:
♠
♥
♦
♣
enum Suit: String {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
}
例如,我怎么做这样的事情:
for suit in Suit {
// do something with suit
print(suit.rawValue)
}
结果示例:
♠
♥
♦
♣
当前回答
这篇文章是相关的https://www.swift-studies.com/blog/2014/6/10/enumerating-enums-in-swift
基本上,提议的解决方案是
enum ProductCategory : String {
case Washers = "washers", Dryers = "dryers", Toasters = "toasters"
static let allValues = [Washers, Dryers, Toasters]
}
for category in ProductCategory.allValues{
//Do something
}
其他回答
更新到Swift 2.2+
func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T> {
var i = 0
return AnyGenerator {
let next = withUnsafePointer(&i) {
UnsafePointer<T>($0).memory
}
if next.hashValue == i {
i += 1
return next
} else {
return nil
}
}
}
它更新了Swift 2.2表单@Kametrixom的答案
Swift 3.0+(非常感谢@Philip)
func iterateEnum<T: Hashable>(_: T.Type) -> AnyIterator<T> {
var i = 0
return AnyIterator {
let next = withUnsafePointer(&i) {
UnsafePointer<T>($0).pointee
}
if next.hashValue == i {
i += 1
return next
} else {
return nil
}
}
}
Swift 4 + 2。
从Swift 4.2 (Xcode 10)开始,只需将协议一致性添加到CaseIterable中,就可以从allCases中受益。要添加这个协议一致性,你只需要在某个地方写:
extension Suit: CaseIterable {}
如果枚举是你自己的,你可以直接在声明中指定一致性:
enum Suit: String, CaseIterable { case spades = "♠"; case hearts = "♥"; case diamonds = "♦"; case clubs = "♣" }
然后下面的代码将打印所有可能的值:
Suit.allCases.forEach {
print($0.rawValue)
}
与早期Swift版本的兼容性(3。X和4.x)
如果您需要支持Swift 3。x或4.0,你可以通过添加以下代码来模仿Swift 4.2的实现:
#if !swift(>=4.2)
public protocol CaseIterable {
associatedtype AllCases: Collection where AllCases.Element == Self
static var allCases: AllCases { get }
}
extension CaseIterable where Self: Hashable {
static var allCases: [Self] {
return [Self](AnySequence { () -> AnyIterator<Self> in
var raw = 0
var first: Self?
return AnyIterator {
let current = withUnsafeBytes(of: &raw) { $0.load(as: Self.self) }
if raw == 0 {
first = current
} else if current == first {
return nil
}
raw += 1
return current
}
})
}
}
#endif
我使用计算属性,它返回所有值的数组(感谢这篇文章http://natecook.com/blog/2014/10/loopy-random-enum-ideas/)。但是,它也使用int原始值,但我不需要在单独的属性中重复枚举的所有成员。
Xcode 6.1在如何使用rawValue获取enum成员方面做了一点改变,所以我修正了listing。还修复了第一个rawValue错误的小错误。
enum ValidSuits: Int {
case Clubs = 0, Spades, Hearts, Diamonds
func description() -> String {
switch self {
case .Clubs:
return "♣︎"
case .Spades:
return "♠︎"
case .Diamonds:
return "♦︎"
case .Hearts:
return "♥︎"
}
}
static var allSuits: [ValidSuits] {
return Array(
SequenceOf {
() -> GeneratorOf<ValidSuits> in
var i=0
return GeneratorOf<ValidSuits> {
return ValidSuits(rawValue: i++)
}
}
)
}
}
这看起来像一个黑客,但如果你使用原始值,你可以这样做
enum Suit: Int {
case Spades = 0, Hearts, Diamonds, Clubs
...
}
var suitIndex = 0
while var suit = Suit.fromRaw(suitIndex++) {
...
}
enum Rank: Int
{
case Ace = 0
case Two, Three, Four, Five, Six, Seve, Eight, Nine, Ten
case Jack, Queen, King
case Count
}
enum Suit : Int
{
case Spades = 0
case Hearts, Diamonds, Clubs
case Count
}
struct Card
{
var rank:Rank
var suit:Suit
}
class Test
{
func makeDeck() -> Card[]
{
let suitsCount:Int = Suit.Count.toRaw()
let rankCount:Int = Rank.Count.toRaw()
let repeatedCard:Card = Card(rank:Rank.Ace, suit:Suit.Spades)
let deck:Card[] = Card[](count:suitsCount*rankCount, repeatedValue:repeatedCard)
for i:Int in 0..rankCount
{
for j:Int in 0..suitsCount
{
deck[i*suitsCount+j] = Card(rank: Rank.fromRaw(i)!, suit: Suit.fromRaw(j)!)
}
}
return deck
}
}
根据Rick的回答:这要快5倍