Enum上的内省和迭代

时间:2015-08-25 19:11:50

标签: swift enums swift2 introspection

是否有可能以编程方式找出有多少"个案"一个Enum在Swift 2中有迭代它们吗?

这段代码没有编译,但是它让你知道我想要实现的目标:

enum HeaderStyles{

    case h1
    case h2
    case h3
}

for item in HeaderStyles{
    print(item)
}

2 个答案:

答案 0 :(得分:6)

迭代所有情况的最简单方法是创建一个返回Array个的计算属性:

enum SomeEnum {
    case Zero, One, Two

    static var allCases: [SomeEnum] {
        return [.Zero, .One, .Two]
    }
}

如果您需要自动数组,可以使用Int作为rawValue,这样,如果添加其他case,则无需更改任何代码:

Swift 3/4: ++--已移除,anyGenerator已重命名为AnyIterator

enum SomeEnum: Int {
    case Zero, One, Two

    static var allCases: [SomeEnum] {
        var i = 0
        return Array(AnyIterator{
            let newEnum = SomeEnum(rawValue: i)
            i += 1
            return newEnum
        })
    }
}

Swift 2

enum SomeEnum: Int {
    case Zero, One, Two

    static var allCases: [SomeEnum] {
        var i = 0
        return Array(anyGenerator{ SomeEnum(rawValue: i++) })
    }
}

在这两种情况下,你都会这样使用它:

for num in SomeEnum.allCases {
    // ...
}

答案 1 :(得分:3)

您可以编写提供该迭代​​功能的通用结构。在下面的示例中,枚举原始值必须以0开头(默认情况下是这样)并且原始值之间没有间隙(不能丢失原始值,如0,1,2,3,5 - 4) )

public struct EnumGenerator<T> : GeneratorType, SequenceType {
    private let enumInit: Int -> T?
    private var i: Int = 0
    public mutating func next() -> T? { return enumInit(i++) }
    public init(_ initFunc: Int -> T?){ self.enumInit = initFunc}
}

enum HeaderStyles:Int{
    case h1
    case h2
    case h3
}

for item in EnumGenerator(HeaderStyles.init){
    print(item)
}