使用只执行一次的闭包和AnyGenerator初始化all
@vacawama 展示了如何使用只执行一次的闭包结合enum 的可失败init(rawValue:) 初始值来以通用方式初始化all 数组。前面提到的答案中方法的一个细微变化是交换显式的while 循环和附加AnyGenerator 的数组:
enum Type: Int {
case A = 0, B, C, D, E, F, G, H
static let all: [Type] = {
var rValue = 0
return AnyGenerator<Type> {
defer { rValue += 1 }
return Type(rawValue: rValue)
}.map{$0}
}()
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
这在 rawValue 只是 ++ 增加 (0, 1, 2, ...) 的条件下有效。
通过使enum符合SequenceType来初始化all
作为另一种选择,由于您的 rawValue 是整数顺序的 (++),您可以让您的 enum 符合 SequenceType,在这种情况下,可以轻松生成所有案例的数组只需使用.map
enum Type: Int, SequenceType {
case A = 0, B, C, D, E, F, G, H
init() { self = A } // Default (first) case intializer
/* conform Type to SequenceType (here: enables only
simple (self.rawValue)...last traversing) */
func generate() -> AnyGenerator<Type> {
var rValue = self.rawValue
return AnyGenerator {
defer { rValue += 1 }
return Type(rawValue: rValue)
}
}
/* use the fact that Type conforms to SequenceType to neatly
initialize your static all array */
static let all = Type().map { $0 }
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
仅应用此一致性来初始化静态 all 数组可能有点矫枉过正,但如果您希望能够使用 enum 的其他方面,这是一个可行的替代方案符合SequenceType
for typeCase in Type() {
// treat each type ...
print(typeCase, terminator: " ")
} // A B C D E F G H
for caseFromEAndForward in Type.E {
print(caseFromEAndForward, terminator: " ")
} // E F G H
使用flatMap根据rawValue的范围初始化案例
最后,作为@appzYourLife neat solution的变体,如果你有很多情况,你可以在rawValue的范围内使用flatMap操作来初始化静态allValues数组,例如
enum Type: Int {
case A = 0, B, C, D, E, F, G, H
static let all = (A.rawValue...H.rawValue)
.flatMap{ Type(rawValue: $0) }
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
然而,这种方法实际上并没有任何实际用途,因为一般大小方法(@vacawama:s 或上面的SequenceType)对于许多情况下的枚举总是更可取的。我可以看到的可能用例是不同情况下的rawValue 是否是连续的但不仅仅是++,例如如果rawValue 用于某些位掩码
// ...
case A = 0, B = 2, C = 4, D = 8, E = 16, F = 32, G = 64, H = 128
上述方法将使用暴力破解rawValue 的范围,其中少数实际上对应于实际情况。有点浪费,但由于它是一次性静态初始化,这应该不是问题。