[英]Enum class in swift
我試圖創建一個具有類型和返回所有類型的函數的枚舉類。
最初,我的對象類中有我的枚舉和一個將這些作為數組返回的函數:
class someClass: Mappable {
enum Type: Int {
case A = 0
case B = 1
case C = 2
}
}
}
func getAllTypes() -> [Type] {
return [Type.A, Type.B, Type.C]
}
}
我想從我的對象類中提取它的原因是因為這個類型也在其他類中使用,我不想復制任何不必要的代碼。
我可以設法對枚舉進行子類化,但不能對返回數組中所有類型的函數進行子類化。
任何幫助將不勝感激。
AnyGenerator
初始化all
@vacawama展示了如何使用僅執行一次的閉包以及enum
的可失敗init(rawValue:)
初始值設定項以通用方式初始化all
數組。 前面提到的答案中方法的一個細微變化是交換顯式的while
循環和附加有AnyGenerator
數組:
enum Type: Int {
case A = 0, B, C, D, E, F, G, H
static let all: [Type] = {
var rValue = 0
return AnyGenerator<Type> {
defer { rValue += 1 }
return Type(rawValue: rValue)
}.map{$0}
}()
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
這在rawValue
只是++
增加( 0, 1, 2, ...
)的條件下rawValue
。
enum
符合SequenceType
來初始化all
作為另一種選擇,由於您的rawValue
是整數順序( ++
),您可以讓您的enum
符合SequenceType
,在這種情況下,只需使用.map
即可輕松生成所有案例的數組
enum Type: Int, SequenceType {
case A = 0, B, C, D, E, F, G, H
init() { self = A } // Default (first) case intializer
/* conform Type to SequenceType (here: enables only
simple (self.rawValue)...last traversing) */
func generate() -> AnyGenerator<Type> {
var rValue = self.rawValue
return AnyGenerator {
defer { rValue += 1 }
return Type(rawValue: rValue)
}
}
/* use the fact that Type conforms to SequenceType to neatly
initialize your static all array */
static let all = Type().map { $0 }
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
僅應用此一致性來初始化靜態all
數組可能有點矯枉過正,但如果您希望能夠使用符合SequenceType
enum
其他方面, all
是一個合理的選擇
for typeCase in Type() {
// treat each type ...
print(typeCase, terminator: " ")
} // A B C D E F G H
for caseFromEAndForward in Type.E {
print(caseFromEAndForward, terminator: " ")
} // E F G H
flatMap
初始化基於rawValue
范圍的rawValue
最后,作為@appzYourLife 簡潔解決方案的變體,如果您有很多情況,您可以在rawValue
的范圍上使用flatMap
操作來初始化靜態allValues
數組,例如
enum Type: Int {
case A = 0, B, C, D, E, F, G, H
static let all = (A.rawValue...H.rawValue)
.flatMap{ Type(rawValue: $0) }
}
print(Type.all)
// [Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H]
然而,這種方法實際上並沒有任何實際用途,因為一般大小方法( @vacawama:s或上面的SequenceType
)對於許多情況的枚舉總是更可取的。 我可以看到的可能用例是,如果不同情況的rawValue
是連續的,而不是簡單的++
,例如,如果rawValue
用於某些位掩碼
// ...
case A = 0, B = 2, C = 4, D = 8, E = 16, F = 32, G = 64, H = 128
上面的方法將使用一種通過rawValue
的范圍強制執行的方法,其中少數實際上對應於實際情況。 有點浪費,但由於它是一次性靜態初始化,所以這應該不是問題。
為什么不簡單地向枚舉類型添加靜態屬性?
enum Type: Int {
case A = 0, B, C
static let all = [A, B, C]
}
如果您的rawValue
是連續的Int
,您可以利用Type(rawValue:)
初始值設定項將失敗並為非法值返回nil
來自動計算Type.all
而無需顯式列出值或設置范圍。 如果您向枚舉添加更多案例,它將自動調整:
enum Type: Int {
case A, B, C, D, E, F, G, H, I, J, K
static let all: [Type] = {
var all: [Type] = []
var value = 0
while let e = Type(rawValue: value) {
all.append(e)
value += 1
}
return all
}()
}
print(Type.all)
[Type.A, Type.B, Type.C, Type.D, Type.E, Type.F, Type.G, Type.H, Type.I, Type.J, Type.K]
您可以定義一個包含枚舉所有可能值的靜態數組:
static let allValues = [A, B, C]
然后你可以在你想要的地方使用它:
var allEnumValues = Type.allValues
如果它也在其他類中使用,那么不要將它放在一個類中
class YourClass : Mappable {
}
enum Type: Int {
case A = 0
case B = 1
case C = 2
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.