枚举
定义和使用
使用enum
关键词来创建枚举并且把它们的整个定义放在一对大括号内,使用case
关键字来定义一个新的枚举成员值。
enum CompassPoint {
case north
case south
case east
case west
}
使用
let direction: CompassPoint = .north
使用Switch
语句匹配枚举值
case .north:
print("direction is north")
case .south:
print("direction is south")
case .east:
print("direction is east")
case .west:
print("direction is west")
}
关联值
你可以定义Swift
枚举来存储任意类型的关联值,如果需要的话,每个枚举成员的关联值类型可以各不相同。枚举的这种特性跟其他语言中的可识别联合discriminated unions
,标签联合tagged unions
,或者变体variants
相似。
定义一个名为Barcode
的枚举类型,它的一个成员值是具有(Int,Int,Int,Int)
类型关联值的upc
,另一个成员值是具有String
类型关联值的qrCode
。
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
然后可以使用任意一种条形码类型创建新的条形码,例如:
var productBarcode = Barcode.upc(8, 0085, 2106, 3)
同一个商品可以被分配一个不同类型的条形码,例如:
productBarcode = Barcode.qrCode("ABCDEFGHIJKLMNOP")
原始值
枚举成员可以被默认值(称为原始值)预填充,这些原始值的类型必须相同。
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
原始值的隐式赋值
在使用原始值为整数或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值,Swift
将会自动为你赋值。
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Plant.mercury
的显式原始值为1
,Planet.venus
的隐式原始值为2
,依次类推。
使用原始值初始化枚举实例
如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做rawValue
的参数,参数类型即为原始值类型,返回值则是枚举成员或nil
。你可以使用这个初始化方法来创建一个新的枚举实例。
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 类型为 Planet? 值为 Planet.uranus
let impossiblePlanet = Planet(rawValue: 11)
print(impossiblePlanet as Any) // nil
递归枚举
递归枚举是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上indirect
来表示该成员可递归。
例如,下面的例子中,枚举类型存储了简单的算术表达式:
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
你也可以在枚举类型开头加上indirect
关键字来表明它的所有成员都是可递归的:
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
上面定义的枚举类型可以存储三种算术表达式:纯数字、两个表达式相加、两个表达式相乘。
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
要操作具有递归性质的数据结构,使用递归函数是一种直截了当的方式。例如,下面是一个对算术表达式求值的函数:
func evaluate(_ expression: ArithmeticExpression) -> Int {
switch expression {
case let .number(value):
return value
case let .addition(left, right):
return evaluate(left) + evaluate(right)
case let .multiplication(left, right):
return evaluate(left) * evaluate(right)
}
}
print(evaluate(product))
// 打印 "18"
该函数如果遇到纯数字,就直接返回该数字的值。如果遇到的是加法或乘法运算,则分别计算左边表达式和右边表达式的值,然后相加或相乘。
网友评论