Swift Enum

Swift中枚举Enumerations,定义更加简便、功能也更为强大。

语法

定义枚举

定义很简单,不用像ObjC一样,使用typedef。

1
2
3
4
enum Day: Int {
// 开头数字,后面忽略。
case Monday = 1, Tuesday, Wednesday
}

除了整型外,还可以使用CharacterString 作为行值

1
2
3
enum IllegalCharacter: Character {
case Tab = "\t"
}

一般情况,我们用数值,字符串还表达枚举的意义,但有时枚举本身说明了其内部意思,不再需要用行值进行补充。

1
2
3
4
enum Direction {
// 像方向,本身就说明了自己。转成Int, String 都没有意义
case North, South, East, West
}

使用枚举

1
2
3
4
5
6
// 类型推导
let day = Day.Tuesday
// 简化前缀,只能在修改时(赋值时不行)。
let label = UILabel()
label.textAlignment = .Right

Enum 类型转换

可以通过rawValue 来获取 Enum 的行值。

1
2
// 这里的dayNumber 自动推导为 Int 型
let dayNumber = Day.Thursday.rawValue

Associated Values (相关值)

Swift 的枚举存储任何类型的相关值,如果需要的话,每个成员的数据类型可以是各不相同的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum Barcode {
case UPCA(Int, Int, Int)
case QRCode(String)
}
// 下面的调用,完全就是结构体的用法啊。太NB了。
var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
switch productBarcode {
case .UPCA(let numberSystem, let identifier, let check):
case .QRCode(let productCode):
println("QR code with value of \(productCode).")
}

在枚举中,有可能出现这种情况,飞机正点、晚点,但晚点多长时间,这样的关联值,应如何表示?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum TrainStatus {
case OnTime
case Delayed(Int)
}
// 调用
let status = .Delayed(42)
switch status {
case .OnTime:
println("on time")
case .Delayed(let mins):
println("delayed \(mins) mins")
}

初始化 & 算值属性

枚举可以添加初始化方法和算值属性(无法使用储值属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
enum TrainStatus {
case OnTime, Delayed(Int)
init() {
self = OnTime
}
var description: String {
switch self {
case OnTime:
return "准时到达"
case Delayed(let minutes):
return "延误 \(minutes) 分钟"
}
}
}
// 初始化默认值
var status = TrainStatus()
// 调用算值属性
println("列⻋车已\(status.description)")

枚举中还可以添加方法

Nested Types

如果一个Enum只属于特定类,可以把 Enum 定义在类中,如果在类外想使用,通过 Train.Status 来调用。

1
2
3
4
5
6
7
8
9
10
class Train {
enum Status {
case OnTime, Delayed(Int)
init() {
self = OnTime
}
var description: String { ... }
}
var status = Status()
}

模式匹配

在Swift 控制流程中,可以用区间值做模式匹配。

  • 增强可读性:模式匹配让验证代码变得间接而且可以互相组合
  • 增强安全性:在对应条件满足时再进行值绑定
1
2
3
4
5
6
7
8
9
10
11
12
13
let status = .Delayed(42)
// 除了上面示例中使用case 的方法外,还可以在.Delayed的区间进行匹配
switch status {
case .OnTime:
println("on time")
case .Delayed(1):
println("Oh, haha")
case .Delayed(2...60): // 具体匹配
println("Not so happy")
case .Delayed(_): // 可以不写
print("xxx")
}

模式组合

1
2
3
4
5
6
7
8
9
10
11
12
13
enum VacationStatus {
case Traveling(TrainStatus)
case Relaxing(daysLeft: Int)
}
// 判断时要逐级判断
switch vacationStatus {
case .Traveling(.OnTime):
// statement
case .Traveling(.Delayed(1...15)):
// statement
case .Traveling(.Delayed(_)):
}

REF::