如何确定Swift enum中的案例数?
(我希望避免手动枚举所有值,或者如果可能的话使用旧的“enum_count技巧”。)
如何确定Swift enum中的案例数?
(我希望避免手动枚举所有值,或者如果可能的话使用旧的“enum_count技巧”。)
当前回答
enum EnumNameType: Int {
case first
case second
case third
static var count: Int { return EnumNameType.third.rawValue + 1 }
}
print(EnumNameType.count) //3
OR
enum EnumNameType: Int {
case first
case second
case third
case count
}
print(EnumNameType.count.rawValue) //3
*在Swift 4.2 (Xcode 10)可以使用:
enum EnumNameType: CaseIterable {
case first
case second
case third
}
print(EnumNameType.allCases.count) //3
其他回答
我写了一个简单的扩展,它给所有枚举的原始值是整数一个count属性:
extension RawRepresentable where RawValue: IntegerType {
static var count: Int {
var i: RawValue = 0
while let _ = Self(rawValue: i) {
i = i.successor()
}
return Int(i.toIntMax())
}
}
不幸的是,它给了计数属性OptionSetType,它不会正常工作,所以这里是另一个版本,需要显式符合CaseCountable协议的任何枚举的情况下,你想要计数:
protocol CaseCountable: RawRepresentable {}
extension CaseCountable where RawValue: IntegerType {
static var count: Int {
var i: RawValue = 0
while let _ = Self(rawValue: i) {
i = i.successor()
}
return Int(i.toIntMax())
}
}
它与Tom Pelaia发布的方法非常相似,但适用于所有整数类型。
只是想共享一个解决方案时,你有一个枚举与相关的值。
enum SomeEnum {
case one
case two(String)
case three(String, Int)
}
CaseIterable不会自动提供allcase。 我们不能为枚举提供像Int这样的原始类型来计算case计数。
我们能做的是使用开关的功率和通过关键字。
extension SomeEnum {
static var casesCount: Int {
var sum = 0
switch Self.one { // Potential problem
case one:
sum += 1
fallthrough
case two:
sum += 1
fallthrough
case three:
sum += 1
}
return sum
}
}
现在你可以说someenume。casescount。
备注:
赛尔夫开关还是有问题。一个{…,我们硬编码了第一个案例。您可以很容易地破解这个解决方案。但我只是将它用于单元测试,所以这不是问题。 如果您经常需要在枚举中获得带有关联值的case计数,请考虑代码生成。
我定义了一个可重用的协议,它根据Nate Cook发布的方法自动执行案例计数。
protocol CaseCountable {
static var caseCount: Int { get }
}
extension CaseCountable where Self: RawRepresentable, Self.RawValue == Int {
internal static var caseCount: Int {
var count = 0
while let _ = Self(rawValue: count) {
count += 1
}
return count
}
}
然后我可以重用这个协议,例如:
enum Planet : Int, CaseCountable {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
//..
print(Planet.caseCount)
扩展Matthieu Riegler的回答,这是一个Swift 3的解决方案,不需要使用泛型,可以很容易地使用枚举类型EnumType.elementsCount调用:
extension RawRepresentable where Self: Hashable {
// Returns the number of elements in a RawRepresentable data structure
static var elementsCount: Int {
var i = 1
while (withUnsafePointer(to: &i, {
return $0.withMemoryRebound(to: self, capacity: 1, { return
$0.pointee })
}).hashValue != 0) {
i += 1
}
return i
}
我有一篇博客文章详细介绍了这一点,但只要你的枚举的原始类型是一个整数,你可以这样添加一个计数:
enum Reindeer: Int {
case Dasher, Dancer, Prancer, Vixen, Comet, Cupid, Donner, Blitzen
case Rudolph
static let count: Int = {
var max: Int = 0
while let _ = Reindeer(rawValue: max) { max += 1 }
return max
}()
}