如何确定Swift enum中的案例数?

(我希望避免手动枚举所有值,或者如果可能的话使用旧的“enum_count技巧”。)


当前回答

对于我的用例,在一个代码库中,多人可以向一个枚举添加键,这些情况都应该在allKeys属性中可用,重要的是要根据枚举中的键验证allKeys。这是为了避免有人忘记将他们的密钥添加到所有密钥列表。将allKeys数组的计数(首先作为一个集合创建,以避免被欺骗)与枚举中的键数量相匹配,可确保它们都存在。

上面的一些答案显示了在Swift 2中实现这一点的方法,但在Swift 3中没有任何方法。以下是Swift 3的格式化版本:

static func enumCount<T: Hashable>(_ t: T.Type) -> Int {
    var i = 1
    while (withUnsafePointer(to: &i) {
      $0.withMemoryRebound(to:t.self, capacity:1) { $0.pointee.hashValue != 0 }
    }) {
      i += 1
    }
    return i
}

static var allKeys: [YourEnumTypeHere] {
    var enumSize = enumCount(YourEnumTypeHere.self)

    let keys: Set<YourEnumTypeHere> = [.all, .your, .cases, .here]
    guard keys.count == enumSize else {
       fatalError("Missmatch between allKeys(\(keys.count)) and actual keys(\(enumSize)) in enum.")
    }
    return Array(keys)
}

根据您的用例,您可能希望只在开发中运行测试,以避免在每个请求上使用allKeys的开销

其他回答

我有一篇博客文章详细介绍了这一点,但只要你的枚举的原始类型是一个整数,你可以这样添加一个计数:

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
    }()
}

这种函数能够返回枚举的计数。

斯威夫特2:

func enumCount<T: Hashable>(_: T.Type) -> Int {
    var i = 1
    while (withUnsafePointer(&i) { UnsafePointer<T>($0).memory }).hashValue != 0 {
        i += 1
    }
    return i
}

斯威夫特3:

func enumCount<T: Hashable>(_: T.Type) -> Int {
   var i = 1
   while (withUnsafePointer(to: &i, {
      return $0.withMemoryRebound(to: T.self, capacity: 1, { return $0.pointee })
   }).hashValue != 0) {
      i += 1
   }
      return i
   }

在Swift 4.2 (Xcode 10)中,你可以声明 符合CaseIterable协议,这适用于所有 没有关联值的枚举:

enum Stuff: CaseIterable {
    case first
    case second
    case third
    case forth
}

病例数现在是简单地用

print(Stuff.allCases.count) // 4

有关更多信息,请参见

SE-0194枚举案例的派生集合

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

带索引的Enum

enum eEventTabType : String {
    case Search     = "SEARCH"
    case Inbox      = "INBOX"
    case Accepted   = "ACCEPTED"
    case Saved      = "SAVED"
    case Declined   = "DECLINED"
    case Organized  = "ORGANIZED"

    static let allValues = [Search, Inbox, Accepted, Saved, Declined, Organized]
    var index : Int {
       return eEventTabType.allValues.indexOf(self)!
    }
}

计数:eEventTabType.allValues.count

index: objeceventtabtype .index

享受:)