enum Suit: String {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
}
例如,我怎么做这样的事情:
for suit in Suit {
// do something with suit
print(suit.rawValue)
}
结果示例:
♠
♥
♦
♣
enum Suit: String {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
}
例如,我怎么做这样的事情:
for suit in Suit {
// do something with suit
print(suit.rawValue)
}
结果示例:
♠
♥
♦
♣
当前回答
另一个解决方案:
enum Suit: String {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
static var count: Int {
return 4
}
init(index: Int) {
switch index {
case 0: self = .spades
case 1: self = .hearts
case 2: self = .diamonds
default: self = .clubs
}
}
}
for i in 0..<Suit.count {
print(Suit(index: i).rawValue)
}
其他回答
我的解决方案是声明一个包含所有枚举可能性的数组。所以for循环可以遍历所有这些。
//Function inside struct Card
static func generateFullDeck() -> [Card] {
let allRanks = [Rank.Ace, Rank.Two, Rank.Three, Rank.Four, Rank.Five, Rank.Six, Rank.Seven, Rank.Eight, Rank.Nine, Rank.Ten, Rank.Jack, Rank.Queen, Rank.King]
let allSuits = [Suit.Hearts, Suit.Diamonds, Suit.Clubs, Suit.Spades]
var myFullDeck: [Card] = []
for myRank in allRanks {
for mySuit in allSuits {
myFullDeck.append(Card(rank: myRank, suit: mySuit))
}
}
return myFullDeck
}
//actual use:
let aFullDeck = Card.generateFullDeck() //Generate the desired full deck
var allDesc: [String] = []
for aCard in aFullDeck {
println(aCard.simpleDescription()) //You'll see all the results in playground
}
我创建了一个实用函数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与case的索引相同。 从无效索引位转换的枚举值的. hashvalue为0。
为Swift2修改,并从@Kametrixom的回答中实现了选角想法:
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
}
}
针对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
}
}
另一个解决方案:
enum Suit: String {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
static var count: Int {
return 4
}
init(index: Int) {
switch index {
case 0: self = .spades
case 1: self = .hearts
case 2: self = .diamonds
default: self = .clubs
}
}
}
for i in 0..<Suit.count {
print(Suit(index: i).rawValue)
}
在Swift中,枚举类型可以像EnumType一样访问。案例:
let tableView = UITableView(frame: self.view. view)UITableViewStyle.Plain)
大多数情况下,只有当您有几个选项可以使用,并且确切地知道在每个选项上要做什么时,才会使用枚举类型。
在处理枚举类型时,使用for-in结构没有太大意义。
你可以这样做,例如:
func sumNumbers(numbers : Int...) -> Int {
var sum = 0
for number in numbers{
sum += number
}
return sum
}
有时,您可能会处理具有底层原始整数类型的枚举类型,这种类型在整个软件开发生命周期中都会发生变化。下面是一个很适合这种情况的例子:
public class MyClassThatLoadsTexturesEtc
{
//...
// Colors used for gems and sectors.
public enum Color: Int
{
// Colors arranged in order of the spectrum.
case First = 0
case Red, Orange, Yellow, Green, Blue, Purple, Pink
// --> Add more colors here, between the first and last markers.
case Last
}
//...
public func preloadGems()
{
// Preload all gems.
for i in (Color.First.toRaw() + 1) ..< (Color.Last.toRaw())
{
let color = Color.fromRaw(i)!
loadColoredTextures(forKey: color)
}
}
//...
}