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)
}
结果示例:
♠
♥
♦
♣
当前回答
我添加了函数count(),并迭代值:
public enum MetricType: Int {
case mvps = 0
case allNBA = 1
case championshipRings = 2
case finalAppearances = 3
case gamesPlayed = 4
case ppg = 5
static func count() -> Int {
return (ppg.rawValue) + 1
}
static var allValues: [MetricType] {
var array: [MetricType] = Array()
var item : MetricType = MetricType.mvps
while item.rawValue < MetricType.count() {
array.append(item)
item = MetricType(rawValue: (item.rawValue + 1))!
}
return array
}
}
其他回答
在处理Swift 2.0时,以下是我的建议:
我已经将原始类型添加到Suit enum
enum Suit: Int {
然后:
struct Card {
var rank: Rank
var suit: Suit
func fullDeck()-> [Card] {
var deck = [Card]()
for i in Rank.Ace.rawValue...Rank.King.rawValue {
for j in Suit.Spades.rawValue...Suit.Clubs.rawValue {
deck.append(Card(rank:Rank(rawValue: i)! , suit: Suit(rawValue: j)!))
}
}
return deck
}
}
编辑: 快速进化提案SE-0194枚举案例派生集合为这个问题提出了一个水平的解决方案。我们在Swift 4.2和更新版本中看到了它。该提案还指出了一些变通方法,这些方法与这里已经提到的一些方法类似,但可能会很有趣。
为了完整起见,我也会保留我原来的职位。
这是基于@Peymmankh的回答的另一种方法,适用于Swift 3。
public protocol EnumCollection: Hashable {}
extension EnumCollection {
public static func allValues() -> [Self] {
typealias S = Self
let retVal = AnySequence { () -> AnyIterator<S> in
var raw = 0
return AnyIterator {
let current = withUnsafePointer(to: &raw) {
$0.withMemoryRebound(to: S.self, capacity: 1) { $0.pointee }
}
guard current.hashValue == raw else { return nil }
raw += 1
return current
}
}
return [S](retVal)
}
更新到Swift 2.2+
func iterateEnum<T: Hashable>(_: T.Type) -> AnyGenerator<T> {
var i = 0
return AnyGenerator {
let next = withUnsafePointer(&i) {
UnsafePointer<T>($0).memory
}
if next.hashValue == i {
i += 1
return next
} else {
return nil
}
}
}
它更新了Swift 2.2表单@Kametrixom的答案
Swift 3.0+(非常感谢@Philip)
func iterateEnum<T: Hashable>(_: T.Type) -> AnyIterator<T> {
var i = 0
return AnyIterator {
let next = withUnsafePointer(&i) {
UnsafePointer<T>($0).pointee
}
if next.hashValue == i {
i += 1
return next
} else {
return nil
}
}
}
有时,您可能会处理具有底层原始整数类型的枚举类型,这种类型在整个软件开发生命周期中都会发生变化。下面是一个很适合这种情况的例子:
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)
}
}
//...
}
Swift 4 + 2。
从Swift 4.2 (Xcode 10)开始,只需将协议一致性添加到CaseIterable中,就可以从allCases中受益。要添加这个协议一致性,你只需要在某个地方写:
extension Suit: CaseIterable {}
如果枚举是你自己的,你可以直接在声明中指定一致性:
enum Suit: String, CaseIterable { case spades = "♠"; case hearts = "♥"; case diamonds = "♦"; case clubs = "♣" }
然后下面的代码将打印所有可能的值:
Suit.allCases.forEach {
print($0.rawValue)
}
与早期Swift版本的兼容性(3。X和4.x)
如果您需要支持Swift 3。x或4.0,你可以通过添加以下代码来模仿Swift 4.2的实现:
#if !swift(>=4.2)
public protocol CaseIterable {
associatedtype AllCases: Collection where AllCases.Element == Self
static var allCases: AllCases { get }
}
extension CaseIterable where Self: Hashable {
static var allCases: [Self] {
return [Self](AnySequence { () -> AnyIterator<Self> in
var raw = 0
var first: Self?
return AnyIterator {
let current = withUnsafeBytes(of: &raw) { $0.load(as: Self.self) }
if raw == 0 {
first = current
} else if current == first {
return nil
}
raw += 1
return current
}
})
}
}
#endif