Nếu bạn cho enum một giá trị Int thô nó sẽ giúp việc lặp dễ dàng hơn nhiều.
Ví dụ: bạn có thể sử dụng anyGenerator
để có được một trình tạo có thể liệt kê các giá trị của bạn:
enum Suit: Int, CustomStringConvertible {
case Spades, Hearts, Diamonds, Clubs
var description: String {
switch self {
case .Spades: return "Spades"
case .Hearts: return "Hearts"
case .Diamonds: return "Diamonds"
case .Clubs: return "Clubs"
}
}
static func enumerate() -> AnyGenerator<Suit> {
var nextIndex = Spades.rawValue
return anyGenerator { Suit(rawValue: nextIndex++) }
}
}
// You can now use it like this:
for suit in Suit.enumerate() {
suit.description
}
// or like this:
let allSuits: [Suit] = Array(Suit.enumerate())
Tuy nhiên, điều này trông giống như một mô hình khá phổ biến, sẽ không hay nếu chúng ta có thể làm cho bất kỳ kiểu liệt kê nào chỉ đơn giản là tuân thủ một giao thức? Vâng với Swift 2.0 và giao thức mở rộng, bây giờ chúng ta có thể!
Đơn giản chỉ cần thêm điều này vào dự án của bạn:
protocol EnumerableEnum {
init?(rawValue: Int)
static func firstValue() -> Int
}
extension EnumerableEnum {
static func enumerate() -> AnyGenerator<Self> {
var nextIndex = firstRawValue()
return anyGenerator { Self(rawValue: nextIndex++) }
}
static func firstRawValue() -> Int { return 0 }
}
Bây giờ bất cứ khi nào bạn tạo một enum (miễn là nó có giá trị Int), bạn có thể làm cho nó có thể đếm được bằng cách tuân thủ giao thức:
enum Rank: Int, EnumerableEnum {
case Ace, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}
// ...
for rank in Rank.enumerate() { ... }
Nếu giá trị enum của bạn không bắt đầu bằng 0
(mặc định), hãy ghi đè firstRawValue
phương thức:
enum DeckColor: Int, EnumerableEnum {
case Red = 10, Blue, Black
static func firstRawValue() -> Int { return Red.rawValue }
}
// ...
let colors = Array(DeckColor.enumerate())
Lớp Suit cuối cùng, bao gồm thay thế simpleDescription
bằng giao thức CustomStringConvertible chuẩn hơn , sẽ trông như thế này:
enum Suit: Int, CustomStringConvertible, EnumerableEnum {
case Spades, Hearts, Diamonds, Clubs
var description: String {
switch self {
case .Spades: return "Spades"
case .Hearts: return "Hearts"
case .Diamonds: return "Diamonds"
case .Clubs: return "Clubs"
}
}
}
// ...
for suit in Suit.enumerate() {
print(suit.description)
}
Cú pháp Swift 3:
protocol EnumerableEnum {
init?(rawValue: Int)
static func firstRawValue() -> Int
}
extension EnumerableEnum {
static func enumerate() -> AnyIterator<Self> {
var nextIndex = firstRawValue()
let iterator: AnyIterator<Self> = AnyIterator {
defer { nextIndex = nextIndex + 1 }
return Self(rawValue: nextIndex)
}
return iterator
}
static func firstRawValue() -> Int {
return 0
}
}