如何枚举带有String类型的枚举? [英] How to enumerate an enum with String type?

查看:432
本文介绍了如何枚举带有String类型的枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如,我该怎么做:

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

结果示例:

♠
♥
♦
♣


推荐答案

我为一个实用函数 iterateEnum()为任意的枚举类型。

I made a utility function iterateEnum() for iterating cases for arbitrary enum types.

以下是使用示例:

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

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

输出:

♠
♥
♦
♣

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

But, this is only for debug or test purpose: This relies on several undocumented current(Swift1.1) compiler behaviors. So, use it at your own risk :)

这是代码:

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

基本思想是:


  • 枚举的内存表示 - 不包括枚举 s与关联类型 - 只是一个案例的索引,当案件的数量是 2 ... 256 ,它与 UInt8相同,当 257 ... 65536 时,它是 UInt16 等等。所以,它可以是相应的无符号整数类型的 unsafeBitcast

  • .hashValue
  • .hashValue 枚举值从无效 index是 0

  • Memory representation of enum - excluding enums with associated types - is just a index of cases, when the count of the cases is 2...256, it's identical to UInt8, when 257...65536, it's UInt16 and so on. So, it can be unsafeBitcast from corresponding unsigned integer types.
  • .hashValue of enum values is the same as the index of the case.
  • .hashValue of enum values bitcasted from invalid index is 0

ADDED:

针对Swift2进行了修订,并从

Revised for Swift2 and implemented casting ideas from @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
    }
}






ADDED:
修订为Swift3


ADDED: Revised for 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
    }
}






ADDED:
修改为Swift3.0.1


ADDED: Revised for Swift3.0.1

func iterateEnum<T: Hashable>(_: T.Type) -> AnyIterator<T> {
    var i = 0
    return AnyIterator {
        let next = withUnsafeBytes(of: &i) { $0.load(as: T.self) }
        if next.hashValue != i { return nil }
        i += 1
        return next
    }
}

这篇关于如何枚举带有String类型的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆