Wenn Sie dem Enum einen Rohwert als Ganzzahlwert geben, wird das Schleifen deutlich einfacher.
Zum Beispiel können Sie anyGenerator
verwenden, um einen Generator zu bekommen, der über Ihre Werte aufzählen kann:
enum Suit: Int, CustomStringConvertible {
case Spades, Hearts, Diamonds, Clubs
var description: String {
switch self {
case .Spades: return "Pik"
case .Hearts: return "Herzen"
case .Diamonds: return "Karo"
case .Clubs: return "Kreuz"
}
}
static func enumerate() -> AnyGenerator {
var nextIndex = Spades.rawValue
return anyGenerator { Suit(rawValue: nextIndex++) }
}
}
// Jetzt können Sie es so verwenden:
for suit in Suit.enumerate() {
suit.description
}
// oder so:
let allSuits: [Suit] = Array(Suit.enumerate())
Allerdings sieht das wie ein ziemlich übliches Muster aus, wäre es nicht schön, wenn wir jede Enum-Typ einfach durch Konformität zu einem Protokoll aufzählbar machen könnten? Mit Swift 2.0 und Protokollerweiterungen ist das jetzt möglich!
Fügen Sie einfach dies zu Ihrem Projekt hinzu:
protocol EnumerableEnum {
init?(rawValue: Int)
static func firstValue() -> Int
}
extension EnumerableEnum {
static func enumerate() -> AnyGenerator {
var nextIndex = firstRawValue()
return anyGenerator { Self(rawValue: nextIndex++) }
}
static func firstRawValue() -> Int { return 0 }
}
Jetzt, jedes Mal wenn Sie ein Enum erstellen (solange es einen Int Rohwert hat), können Sie es durch Konformität zu dem Protokoll aufzählbar machen:
enum Rank: Int, EnumerableEnum {
case Ass, Zwei, Drei, Vier, Fünf, Sechs, Sieben, Acht, Neun, Zehn, Bube, Dame, König
}
// ...
for rank in Rank.enumerate() { ... }
Wenn Ihre Enum-Werte nicht mit 0
beginnen (der Standardwert), überschreiben Sie die Methode firstRawValue
:
enum DeckColor: Int, EnumerableEnum {
case Rot = 10, Blau, Schwarz
static func firstRawValue() -> Int { return Rot.rawValue }
}
// ...
let colors = Array(DeckColor.enumerate())
Die endgültige Suit-Klasse, inklusive Ersetzung von simpleDescription
durch das Standardprotocol CustomStringConvertible, wird so aussehen:
enum Suit: Int, CustomStringConvertible, EnumerableEnum {
case Pik, Herzen, Karo, Kreuz
var description: String {
switch self {
case .Spades: return "Pik"
case .Hearts: return "Herzen"
case .Diamonds: return "Karo"
case .Clubs: return "Kreuz"
}
}
}
// ...
for suit in Suit.enumerate() {
print(suit.description)
}
Swift 3-Syntax:
protocol EnumerableEnum {
init?(rawValue: Int)
static func firstRawValue() -> Int
}
extension EnumerableEnum {
static func enumerate() -> AnyIterator {
var nextIndex = firstRawValue()
let iterator: AnyIterator = AnyIterator {
defer { nextIndex = nextIndex + 1 }
return Self(rawValue: nextIndex)
}
return iterator
}
static func firstRawValue() -> Int {
return 0
}
}