swift – 如何枚举一个枚举字符串类型?

enum Suit: String {
    case spades = "♠"
    case hearts = "♥"
    case diamonds = "♦"
    case clubs = "♣"
}

例如,我该如何做:

for suit in Suit {
    // do something with suit
    print(suit.rawValue)
}

结果示例:

♠
♥
♦
♣
我做了一个实用函数iterateEnum()用于迭代任意枚举类型的情况。

这里是使用示例:

enum Suit:String {
    case Spades = "♠"
    case Hearts = "♥"
    case Diamonds = "♦"
    case Clubs = "♣"
}

for f in iterateEnum(Suit) {
    println(f.rawValue)
}

输出

♠
♥
♦
♣

但是,这只是为了调试或测试目的:这依赖于几个未记录的电流(Swift1.1)编译器行为。所以,使用它在你自己的风险:)

这里是代码

func iterateEnum<T: Hashable>(_: T.Type) -> GeneratorOf<T> {
    var cast: (Int -> T)!
    switch sizeof(T) {
    case 0: return GeneratorOf(GeneratorOfOne(unsafeBitCast((),T.self)))
    case 1: cast = { unsafeBitCast(UInt8(truncatingBitPattern: $0),T.self) }
    case 2: cast = { unsafeBitCast(UInt16(truncatingBitPattern: $0),T.self) }
    case 4: cast = { unsafeBitCast(UInt32(truncatingBitPattern: $0),T.self) }
    case 8: cast = { unsafeBitCast(UInt64($0),T.self) }
    default: fatalError("cannot be here")
    }

    var i = 0
    return GeneratorOf {
        let next = cast(i)
        return next.hashValue == i++ ? next : nil
    }
}

基本思想是:

>枚举的内存表示 – 不包括关联类型的枚举 – 只是案例的索引,当案例的计数为2 … 256时,它与UInt8相同,当257 … 65536时,它的UInt16等。所以,它可以是unsafeBitcast从相应的无符号整数类型。
> .hashValue的枚举值与大小写的索引相同。
>从无效索引位被转换的枚举值的.hashValue为0

添加

修正Swift2和实施从@Kametrixom’s answer的投票想法

func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T> {
    var i = 0
    return anyGenerator {
        let next = withUnsafePointer(&i) { UnsafePointer<T>($0).memory }
        return next.hashValue == i++ ? next : nil
    }
}

添加
修正Swift3

func iterateEnum<T: Hashable>(_: T.Type) -> AnyIterator<T> {
    var i = 0
    return AnyIterator {
        let next = withUnsafePointer(to: &i) {
            $0.withMemoryRebound(to: T.self,capacity: 1) { $0.pointee }
        }
        if next.hashValue != i { return nil }
        i += 1
        return next
    }
}

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...