java string枚举,如何枚举带有String类型的枚举?

这篇博客介绍了如何在Swift中通过一个实用函数`iterateEnum()`来迭代枚举的所有案例,包括对不同大小枚举的处理方式。虽然这个方法依赖于一些未公开的Swift编译器行为,因此只适用于调试或测试,不适合生产环境。文章提供了Swift1.1到Swift3.0.1的代码更新,展示了如何在不同Swift版本下实现该功能。
摘要由CSDN通过智能技术生成

enum Suit: String {

case spades = "♠"

case hearts = "♥"

case diamonds = "♦"

case clubs = "♣"

}

For example, how can I do something like:

for suit in Suit {

// do something with suit

print(suit.rawValue)

}

Resulting example:

解决方案

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

Here is the example usage:

enum Suit:String {

case Spades = "♠"

case Hearts = "♥"

case Diamonds = "♦"

case Clubs = "♣"

}

for f in iterateEnum(Suit) {

println(f.rawValue)

}

outputs:

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 :)

Here is the code:

func iterateEnum(_: T.Type) -> GeneratorOf {

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

}

}

The underlying idea is:

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:

Revised for Swift2 and implemented casting ideas from @Kametrixom's answer

func iterateEnum(_: T.Type) -> AnyGenerator {

var i = 0

return anyGenerator {

let next = withUnsafePointer(&i) { UnsafePointer($0).memory }

return next.hashValue == i++ ? next : nil

}

}

ADDED:

Revised for Swift3

func iterateEnum(_: T.Type) -> AnyIterator {

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:

Revised for Swift3.0.1

func iterateEnum(_: T.Type) -> AnyIterator {

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

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值