微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

原文地址:https://www.jb51.cc/swift/322110.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐