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)
}
结果示例:
♠
♥
♦
♣
当前回答
其他的解决方法都是可行的,但它们都假设了可能的等级和花色的数量,或者第一和最后的等级是什么。的确,在可预见的未来,一副纸牌的布局可能不会有太大变化。然而,一般来说,编写尽可能少假设的代码会更简洁。我的解决方案:
我已经在Suit枚举中添加了一个原始类型,所以我可以使用Suit(rawValue:)来访问Suit案例:
enum Suit: Int {
case Spades = 1
case Hearts, Diamonds, Clubs
func simpleDescription() -> String {
switch self {
case .Spades:
return "spades"
case .Hearts:
return "hearts"
case .Diamonds:
return "diamonds"
case .Clubs:
return "clubs"
}
}
func color() -> String {
switch self {
case .Spades:
return "black"
case .Clubs:
return "black"
case .Diamonds:
return "red"
case .Hearts:
return "red"
}
}
}
enum Rank: Int {
case Ace = 1
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
case Jack, Queen, King
func simpleDescription() -> String {
switch self {
case .Ace:
return "ace"
case .Jack:
return "jack"
case .Queen:
return "queen"
case .King:
return "king"
default:
return String(self.rawValue)
}
}
}
在Card的createDeck()方法实现的下面。init(rawValue:)是一个可失败的初始化式,返回一个可选值。通过在两个while语句中展开并检查它的值,不需要假设Rank或Suit情况的数量:
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
func createDeck() -> [Card] {
var n = 1
var deck = [Card]()
while let rank = Rank(rawValue: n) {
var m = 1
while let suit = Suit(rawValue: m) {
deck.append(Card(rank: rank, suit: suit))
m += 1
}
n += 1
}
return deck
}
}
下面是如何调用createDeck方法:
let card = Card(rank: Rank.Ace, suit: Suit.Clubs)
let deck = card.createDeck()
其他回答
在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
}
对不起,我的回答是具体到我如何在我需要做的事情中使用这篇文章。对于那些无意中遇到这个问题的人,寻找一种方法在枚举中找到一个case,这是一种方法(Swift 2新增):
编辑:小写驼峰现在是Swift 3 enum值的标准
// From apple docs: If the raw-value type is specified as String and you don’t assign values to the cases explicitly, each unassigned case is implicitly assigned a string with the same text as the name of that case.
enum Theme: String
{
case white, blue, green, lavender, grey
}
func loadTheme(theme: String)
{
// this checks the string against the raw value of each enum case (note that the check could result in a nil value, since it's an optional, which is why we introduce the if/let block
if let testTheme = Theme(rawValue: theme)
{
// testTheme is guaranteed to have an enum value at this point
self.someOtherFunction(testTheme)
}
}
对于那些对枚举感到疑惑的人来说,本页上给出的答案包括一个包含所有枚举值的数组的静态var/let是正确的。最新的苹果tvOS示例代码包含了完全相同的技术。
也就是说,他们应该在语言中构建一个更方便的机制(苹果,你在听吗?)
你可以试着像这样列举
enum Planet: String {
case Mercury
case Venus
case Earth
case Mars
static var enumerate: [Planet] {
var a: [Planet] = []
switch Planet.Mercury {
case .Mercury: a.append(.Mercury); fallthrough
case .Venus: a.append(.Venus); fallthrough
case .Earth: a.append(.Earth); fallthrough
case .Mars: a.append(.Mars)
}
return a
}
}
Planet.enumerate // [Mercury, Venus, Earth, Mars]
这是一个相当老的帖子,来自Swift 2.0。现在有一些更好的解决方案,使用了swift 3.0的新特性: 在Swift 3.0中迭代一个Enum
关于这个问题,有一个解决方案,它使用了Swift 4.2的一个新功能(在我写这篇编辑时还没有发布): 我如何得到一个Swift枚举的计数?
在这个帖子中有很多好的解决方案,但其中一些非常复杂。我喜欢尽可能地简化。这里有一个解决方案,可能适用于不同的需求,但我认为它在大多数情况下都很好:
enum Number: String {
case One
case Two
case Three
case Four
case EndIndex
func nextCase () -> Number
{
switch self {
case .One:
return .Two
case .Two:
return .Three
case .Three:
return .Four
case .Four:
return .EndIndex
/*
Add all additional cases above
*/
case .EndIndex:
return .EndIndex
}
}
static var allValues: [String] {
var array: [String] = Array()
var number = Number.One
while number != Number.EndIndex {
array.append(number.rawValue)
number = number.nextCase()
}
return array
}
}
迭代:
for item in Number.allValues {
print("number is: \(item)")
}
下面是我用来迭代枚举和从一个枚举提供多个值类型的方法
enum IterateEnum: Int {
case Zero
case One
case Two
case Three
case Four
case Five
case Six
case Seven
//tuple allows multiple values to be derived from the enum case, and
//since it is using a switch with no default, if a new case is added,
//a compiler error will be returned if it doesn't have a value tuple set
var value: (french: String, spanish: String, japanese: String) {
switch self {
case .Zero: return (french: "zéro", spanish: "cero", japanese: "nuru")
case .One: return (french: "un", spanish: "uno", japanese: "ichi")
case .Two: return (french: "deux", spanish: "dos", japanese: "ni")
case .Three: return (french: "trois", spanish: "tres", japanese: "san")
case .Four: return (french: "quatre", spanish: "cuatro", japanese: "shi")
case .Five: return (french: "cinq", spanish: "cinco", japanese: "go")
case .Six: return (french: "six", spanish: "seis", japanese: "roku")
case .Seven: return (french: "sept", spanish: "siete", japanese: "shichi")
}
}
//Used to iterate enum or otherwise access enum case by index order.
//Iterate by looping until it returns nil
static func item(index: Int) -> IterateEnum? {
return IterateEnum.init(rawValue: index)
}
static func numberFromSpanish(number: String) -> IterateEnum? {
return findItem { $0.value.spanish == number }
}
//use block to test value property to retrieve the enum case
static func findItem(predicate: ((_: IterateEnum) -> Bool)) -> IterateEnum? {
var enumIndex: Int = -1
var enumCase: IterateEnum?
//Iterate until item returns nil
repeat {
enumIndex += 1
enumCase = IterateEnum.item(index: enumIndex)
if let eCase = enumCase {
if predicate(eCase) {
return eCase
}
}
} while enumCase != nil
return nil
}
}
var enumIndex: Int = -1
var enumCase: IterateEnum?
// Iterate until item returns nil
repeat {
enumIndex += 1
enumCase = IterateEnum.item(index: enumIndex)
if let eCase = enumCase {
print("The number \(eCase) in french: \(eCase.value.french), spanish: \(eCase.value.spanish), japanese: \(eCase.value.japanese)")
}
} while enumCase != nil
print("Total of \(enumIndex) cases")
let number = IterateEnum.numberFromSpanish(number: "siete")
print("siete in japanese: \((number?.value.japanese ?? "Unknown"))")
输出如下:
法语中的数字Zero: zéro,西班牙语中的数字cero,日语中的数字nuru 数字一在法语中是un,西班牙语中是uno,日语中是ichi 法语中的数字2是deux,西班牙语中的数字2是dos,日语中的数字2是ni 法语中的“三”是“trois”,西班牙语中的“tres”,日语中的“san” 法语中的“四”是quatre,西班牙语中的“四”是cuatro,日语中的“四”是shi 数字五在法语中是cinq,西班牙语中是cinco,日语中是go 数字6在法语中是Six,西班牙语是seis,日语是roku 法语中的数字“七”是“sept”,西班牙语中的“siete”,日语中的“shichi”
共8例
Siete在日语中的意思是:shichi
更新
我最近创建了一个协议来处理枚举。该协议需要一个Int原始值的enum:
protocol EnumIteration {
//Used to iterate enum or otherwise access enum case by index order. Iterate by looping until it returns nil
static func item(index:Int) -> Self?
static func iterate(item:((index:Int, enumCase:Self)->()), completion:(()->())?) {
static func findItem(predicate:((enumCase:Self)->Bool)) -> Self?
static func count() -> Int
}
extension EnumIteration where Self: RawRepresentable, Self.RawValue == Int {
//Used to iterate enum or otherwise access enum case by index order. Iterate by looping until it returns nil
static func item(index:Int) -> Self? {
return Self.init(rawValue: index)
}
static func iterate(item:((index:Int, enumCase:Self)->()), completion:(()->())?) {
var enumIndex:Int = -1
var enumCase:Self?
//Iterate until item returns nil
repeat {
enumIndex += 1
enumCase = Self.item(enumIndex)
if let eCase = enumCase {
item(index: enumIndex, enumCase: eCase)
}
} while enumCase != nil
completion?()
}
static func findItem(predicate:((enumCase:Self)->Bool)) -> Self? {
var enumIndex:Int = -1
var enumCase:Self?
//Iterate until item returns nil
repeat {
enumIndex += 1
enumCase = Self.item(enumIndex)
if let eCase = enumCase {
if predicate(enumCase:eCase) {
return eCase
}
}
} while enumCase != nil
return nil
}
static func count() -> Int {
var enumIndex:Int = -1
var enumCase:Self?
//Iterate until item returns nil
repeat {
enumIndex += 1
enumCase = Self.item(enumIndex)
} while enumCase != nil
//last enumIndex (when enumCase == nil) is equal to the enum count
return enumIndex
}
}