如何枚举带有String类型的枚举? [英] How to enumerate an enum with String type?
本文介绍了如何枚举带有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
- excludingenum
s with associated types - is just a index of cases, when the count of the cases is2...256
, it's identical toUInt8
, when257...65536
, it'sUInt16
and so on. So, it can beunsafeBitcast
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 is0
ADDED:
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屋!
查看全文