Swift(五) 枚举

枚举

Swift中枚举特点

枚举类型是一等公民(first-class),在 C 语言中枚举将枚举名和一个整型值相对应。Swift 中的枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为“原始”值),则该值的类型可以是字符串,字符,或是一个整型值或浮点数。

枚举枚举支持计算属性,可以定义构造函数,可以遵守协议,可以扩展。

枚举语法

1
2
3
4
5
6
7
8
9
10
11
12
// 默认不为 0,1,2...
enum CompassPoint {
case North
case South
case East
case West
}

// 多个成员值可以在同一行上
enum Planet {
case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
例:
enum CompassPoint {

case North
case South
case West
case East
}


var directionToHead = CompassPoint.North

print(directionToHead)

//
directionToHead = .West

// 在通过switch判断枚举类型时 ,必须穷举出所有情况,
//当不需要匹配每个枚举成员的时候,你可以提供一个默认default分支来涵盖所有未明确被提出的枚举成员:

switch directionToHead {

case .North:
print("north")
case .South:
print("south")
default:
print("default")

}

关联值(Associated Values)

相当于枚举成员可以存储值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//条形码
enum Barcode {

case UPCA(Int, Int, Int, Int)
case QRCode(String)
}

var productBarcode = Barcode.UPCA(8, 8599, 51226, 3)
productBarcode = Barcode.QRCode("ABCDEFGHIJ")

switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
print("QR code: \(productCode).")
}

原始值

1
2
3
4
5
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}

原始值始终不变, 关联值是可以变化的。

原始值的隐藏赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

enum CompassPoint: String {
case North, South, East, West
}

//CompassPoint.South拥有隐式原始值South
let earthsOrder = Planet.Earth.rawValue
// earthsOrder 值为 3

let sunsetDirection = CompassPoint.West.rawValue
// sunsetDirection 值为 "West"

递归枚举

递归枚举(recursive enumeration)是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上indirect来表示该成员可递归。也可以在枚举类型的开头加上indirect关键字来表明所有成员都可以递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//见Xcode
indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}

func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
return value
case .Addition(let left, let right):
return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
return evaluate(left) * evaluate(right)
}
}

// 计算 (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))