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

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


当前回答

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

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

其他回答

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

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

如果实现不反对使用整数enum,你可以添加一个额外的成员值Count来表示枚举中的成员数量-参见下面的例子:

enum TableViewSections : Int {
  case Watchlist
  case AddButton
  case Count
}

现在,您可以通过调用TableViewSections.Count.rawValue来获取枚举中的成员数量,在上面的例子中,它将返回2。

当你在switch语句中处理枚举时,确保在遇到Count成员时抛出断言失败:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  let currentSection: TableViewSections = TableViewSections.init(rawValue:section)!
  switch(currentSection) {
  case .Watchlist:
    return watchlist.count
  case .AddButton:
    return 1
  case .Count:
    assert(false, "Invalid table view section!")
  }
}
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

扩展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 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计数,请考虑代码生成。