枚举
在 Swift 中,枚举类型是一等(first-class)类型。它们采用了很多在传统上只被类(class)所支持的特 性,例如计算型属性(computed properties),用于提供枚举值的附加信息,实例方法(instance method s),用于提供和枚举值相关联的功能。枚举也可以定义构造函数(initializers)来提供一个初始值;可以在原 始实现的基础上扩展它们的功能;还可以遵守协议(protocols)来提供标准的功能。
枚举语法
使用 enum 关键词来创建枚举并且把它们的整个定义放在一对大括号内:
enum CompassPoint {
case North
case South
case East
case West
}
枚举中定义的值(如 North,South,East 和 West )是这个枚举的成员值(或成员)。你使用 case 关键字来 定义一个新的枚举成员值。
*注意与 C 和 Objective-C 不同,Swift 的枚举成员在被创建时不会被赋予一个默认的整型值。在上面的
nt 例子中,North,East 和 West 不会被隐式地赋值为 0,1,2 和 3 。相反,这些枚举成员本身 就是完备的值,这些值的类型是已经明确定义好的 CompassPoint 类型。*
关联值
在Swift中,使用如下方式定义表示两种商品条形码的枚举
enum Barcode {
case UPCA(Int,Int,Int)
case QRCode(String)
}
以上代码可以这么理解:
“定义一个名为 Barcode 的枚举类型,它的一个成员值是具有 (Int,Int,Int) 类型关联值的 UPCA,另一 个成员值是具有 String 类型关联值的 QRCode 。”
var productBarcode = Barcode.UPCA(8,85909,51226,3)
// 同一个商品可以被分配一个不同类型的条形码
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")
原始值
作为关联值的替代选择,枚举成员可以被默认值(称为原始值)预填充,这些原始值的类型必须相同。
这是一个使用 ASCII 码作为原始值的枚举:
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
原始值的隐式赋值
下面的枚举是对之前 Planet 这个枚举的一个细化,利用整型的原始值来表示每个行星在太阳系中的顺序:
enum Planet: Int {
case Mercury = 1,Venus,Earth,Mars,Jupiter,Saturn,Uranus,Neptune
}
在上面的例子中,Plant.Mercury 的显式原始值为 1,Planet.Venus 的隐式原始值为 2,依次类推。
下面的例子是 CompassPoint 枚举的细化,使用字符串类型的原始值来表示各个方向的名称:
enum CompassPoint: String {
case North,East,West
}
上面例子中,CompassPoint.South 拥有隐式原始值 South,依次类推。
使用枚举成员的 rawValue 属性可以访问该枚举成员的原始值:
let earthsOrder = Planet.Earth.rawValue
// earthsOrder 值为 3
let sunsetDirection = CompassPoint.West.rawValue
// sunsetDirection 值为 "West"
// 使用原始值初始化枚举实例
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 类型为 Planet? 值为 Planet.Uranus
递归枚举
递归枚举(recursive enumeration) 是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联 值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上 indirect 来表示该成员可递归。
// 第一种方式
enum ArithmeticExpression {
case Number(Int)
indirect case Addition(ArithmeticExpression,ArithmeticExpression)
indirect case Multiplication(ArithmeticExpression,ArithmeticExpression)
}
// 第二种方式
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)) // 输出 "18"
个人赶脚枚举递归个关联值差不多