枚举(Enumeration):
枚举在Swift中是 first-class types。与C,Objective-C中的枚举相比,Swift中枚举功能更强大。它支持很多只有类才有的特性,如: Properties, Methods, Initialization, Extensions, [Protocols]
1.语法格式
enum EnumName{
case
case
case
...
}
基本的枚举类型
enum Weight {
case light
case Mid
case Heavy
}
注意:
与C和Objective-C不同,Swift枚举情况在创建时不分配默认整数值。在Weight例子中,light,Mid和Heavy不等于隐式0,1和2。
OC的枚举值只支持Int一种类型,Swift的枚举值支持四种类型
整型(Integer)
浮点数(Float Point)
字符串(String)
布尔类型(Boolean)
对于Int
类型的枚举
enum Weight : Int {
case light = 0
case Mid = 1
case Heavy = 2
}
使用枚举的rawValue
属性来访问其原始值:
let weight = Weight.light.rawValue
let middle = Weight.Mid.rawValue
let heavy = Weight.Heavy.rawValue
控制台输出:weight=0,middle=1,heavy=2
其实对于Int
类型的枚举,不必为每种case显示分配原值,Swift将自动
为其分配值,每个case原始值依次加1
,上面的写法可以写成
enum Weight : Int {
case light = 0
case Mid
case Heavy
}
再简单一点可以这样写:
enum Weight : Int {
case light = 0,Mid , Heavy
}
假设我们不设置第一个case值,如下
enum Weight : Int {
case light ,Mid , Heavy
}
控制台输出结果不变:weight=0,middle=1,heavy=2
这是因为第一个case值
默认
为0
对于字符串
类型的枚举成员,举例如下:
enum DogName:String{
case taidi = "taidi"
case fadou = "fadou"
case jinmao = "jinmao"
}
let taidi = DogName.taidi.rawValue
let fadou = DogName.fadou.rawValue
let jinmao = DogName.fadou.rawValue
控制台输出:taidi=taidi,fadou=fadou,jinmao=fadou
对于
字符串
的枚举成员,隐式原始值
为该枚举成员变量的名称,也就是说,上面的写法等同于
enum DogName:String{
case taidi
case fadou
case jinmao
}
在某种情况下,我们需要根据
raw
值去找我们的成员变量
enum Weight : Int {
case light = 0
case Mid = 1
case Heavy = 2
}
let mid = Weight(rawValue: 1)
print(mid)
输出:Optional(Constructor.Weight.Mid),其中Constructor是工程名,Weight是枚举名称
从Optional可以看出返回值是可选类型,这样就避免了传入不存在的raw值,如
let noData = Weight(rawValue: 3)
print(noData)
输出为:nil
2.嵌套枚举
如果你有特定子类型的需求,可以对enum
进行嵌套。这样就允许你为实际的enum
中包含其他明确信息的enum
。以狗狗类型为例,每个狗狗都吃食物,都有玩具,因此所有类型的狗都可以获取同一个食物集合。而其他类型的狗则无法吃这些食物(比如金毛只能啃馒头)。
enum Dog {
enum Food {
case noodles
case dumpling
case meat
}
enum Toys{
case basketball
case football
}
case taidi
case faniu
}
现在,你可以通过层级结构
来描述狗狗允许访问的项目条。
let pet = Dog.taidi
let food = Dog.Food.dumpling
let toys = Dog.Toys.football
3.迭代枚举
当需要迭代枚举中的所有
情况时,需要自定义的枚举遵守CaseIterable
协议
enum Dog:CaseIterable {
case jinmao
case taidi
case faniu
}
let numOfDogKind = Dog.allCases.count
print("numOfDogKind = \(numOfDogKind)")
//numOfDogKind = 3
for dogKind in Dog.allCases{
print(dogKind)
}
//jinmao
//taidi
//faniu
4.关联值(Associated Values)
我们可以定义Swift枚举来存储任何给定类型的关联值,而且每种枚举情况的值类型可以不同。
enum Pet{
//名字和年龄
case dog(String,Int)
//体重
case cat(Float)
}
var result = Pet.dog("老七", 3)
result = Pet.cat(2.0)
print(result)
switch result {
case .dog(let name, let age):
print("dog: name = \(name), age = \(age).")
case .cat(let weight):
print("cat: weight = \(weight)公斤")
如果一个枚举成员的所有关联值都被提取为常量,或者都被提取为变量,为了简洁,你可以只在成员名称前标注一个let或者var:
switch result {
case let .dog(name,age):
print("dog: name = \(name), age = \(age).")
case let .cat(weight):
print("cat: weight = \(weight)公斤")
}
5.包含枚举(Containing Enums)
同样地,你也能够在structs或classes中内嵌枚举。举例:
struct Dog {
enum DogKind {
case jinmao
case taiji
case fadou
}
enum Food {
case noodles
case dumpling
case meat
}
let kind : DogKind
let food : Food
}
let dog = Dog(kind: .fadou, food: .dumpling);
if case let newDog = dog {
print(newDog.kind)
}
//fadou
同样地,这也将有助于我们将相关的信息集中在一个位置。