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中,枚举类型可以像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
}
有一种聪明的方法,尽管令人沮丧,但它说明了两种不同类型的枚举之间的区别。
试试这个:
func makeDeck() -> Card[] {
var deck: Card[] = []
var suits: Suit[] = [.Hearts, .Diamonds, .Clubs, .Spades]
for i in 1...13 {
for suit in suits {
deck += Card(rank: Rank.fromRaw(i)!, suit: suit)
}
}
return deck
}
交易是,一个由数字(原始值)支持的枚举是隐式显式有序的,而一个没有数字支持的枚举是显式隐式无序的。
例如,当我们给枚举值数字时,语言足够狡猾,可以找出数字的顺序。 另一方面,如果我们不给它任何顺序,当我们尝试迭代这些值时,语言就会举起双手说:“是的,但你想先执行哪个??”
其他可以做到这一点(迭代无序枚举)的语言可能是相同的语言,其中所有内容实际上都是一个地图或字典,你可以迭代地图的键,无论是否有任何逻辑顺序。
诀窍是给它提供一些显式排序的东西,在这个例子中,suit的实例在数组中按照我们想要的顺序。一旦你这么说,霉霉就会说“你为什么不一开始就这么说呢?”
另一个简写技巧是在fromRaw函数上使用强制操作符。这说明了关于枚举的另一个“陷阱”,即可能传入的值的范围通常大于枚举的范围。例如,如果我们说Rank.fromRaw(60),就不会返回值,所以我们使用了语言的可选特性,在我们开始使用可选特性的地方,很快就会出现强制。(或者交替if let结构,这对我来说仍然有点奇怪)
Swift 5解决方案:
enum Suit: String, CaseIterable {
case spades = "♠"
case hearts = "♥"
case diamonds = "♦"
case clubs = "♣"
}
// access cases like this:
for suitKey in Suit.allCases {
print(suitKey)
}
如果您仍然想为Rank和Suit使用枚举,这里有一个不那么神秘的例子。如果您想使用for-in循环遍历每个对象,只需将它们收集到一个Array中。
标准52张牌的例子:
enum Rank: Int {
case Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
func name() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
default:
return String(self.toRaw())
}
}
}
enum Suit: Int {
case Diamonds = 1, Clubs, Hearts, Spades
func name() -> String {
switch self {
case .Diamonds:
return "diamonds"
case .Clubs:
return "clubs"
case .Hearts:
return "hearts"
case .Spades:
return "spades"
default:
return "NOT A VALID SUIT"
}
}
}
let Ranks = [
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 Suits = [
Suit.Diamonds,
Suit.Clubs,
Suit.Hearts,
Suit.Spades
]
class Card {
var rank: Rank
var suit: Suit
init(rank: Rank, suit: Suit) {
self.rank = rank
self.suit = suit
}
}
class Deck {
var cards = Card[]()
init() {
for rank in Ranks {
for suit in Suits {
cards.append(Card(rank: rank, suit: suit))
}
}
}
}
var myDeck = Deck()
myDeck.cards.count // => 52
编辑: 快速进化提案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)
}