枚举语法
使用enum关键词来创建枚举并且把它们的整个定义放在一对大括号内:
enum someEnumeration {
//枚举定义
case ....
case ....
case ....
}
eg:下面是枚举表示四个方向
enum CompassPoint {
case North
case South
case East
case West
}
枚举中定义的值(如 North,South,Ease和West)是这个枚举的成员值(或成员)。我们使用case关键字来定义一个新的枚举成员值。
note:与c和objective-c不同,Swift的枚举成员在被创建时不会被赋予一个默认的整型值。在上面的例子中,North,South,East和west不会隐式地赋值为0,1,2,和3.相反,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义号的CompassPoint类型。
多个成员值可以出现在同一行上,用逗号隔开:
enum CompassPoint {
case North,South,East,West
}
每个枚举定义了一个全新的类型。像Swift中其他类型一样,它们的名字必须以一个大写字母开头。给枚举类型起一个单数名字而不是复数名字,以便于代码更加容易理解:
var direction = CompassPoint.South
direction的类型可以在它被CompassPoint的某个值初始化时推断出来。一旦direction被声明为CompassPoint类型,我们就可以使用更短的点语法将其设置为另一个CompassPoint的值:
var direction = CompassPoint.South
direction = .West
使用Switch语句匹配枚举值
我们可以使用Switch语句匹配单个枚举值:
enum CompassPoint {
case North,South,East,West
}
let direction = CompassPoint.South
switch direction {
case .North:
print("north direction")
case .South:
print("South direction")
case .East:
print("East direction")
case .South:
print("south direction")
default:
print("error")
}
关联值
1.我们可以定义Swift枚举来存储任意类型的关联值,如果需要的话,每个枚举成员的关联值类型可以各不相同。
2.在Swift中,使用如下方式定义表示两种商品条形码的枚举:
enum Barcode {
case UPCA(Int,Int,Int,Int)
case QRCode(String)
}
定义一个名为Barcode的枚举类型,它的一个成员值是具有(Int,Int,Int,Int)类型关联值的UPCA,另一个成员值是具有String类型关联值的QRCode。
这个定义不提供任何Int或String类型的关联值,它只是定义了,当Barcode常量和变量等于Barcode.UPCA或Barcode.QRCode时,可以存储的关联值的类型。
enum Barcode {
case UPCA(Int,Int,Int,Int)
case QRCode(String)
}
var product1 = Barcode.UPCA(8, 85909, 51226, 3)
product1 = Barcode.QRCode("ABCDFJJDLSJGLSDGGDS")
switch product1{
case .UPCA(let a,let b,let c,let d):
print("\(a) \(b) \(c) \(d)")
case .QRCode(let code):
print("\(code)")
}
如果一个枚举成员的所有关联值都被提取为常量或者是被提取为变量,为了简洁,你可以只在成员名称前标注一个 let 活着 var:
enum Barcode {
case UPCA(Int,Int,Int,Int)
case QRCode(String)
}
var product1 = Barcode.UPCA(8, 85909, 51226, 3)
product1 = Barcode.QRCode("ABCDFJJDLSJGLSDGGDS")
switch product1{
case let .UPCA( a, b, c, d):
print("\(a) \(b) \(c) \(d)")
case let .QRCode( code):
print("\(code)")
}
原始值
作为关联值的替代选择,枚举成员可以被默认值(称为原始值)预填充,这些原始值的类型必须相同。
enum ASCIIControlCharacter:Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
枚举类型ASCIIControlCharacter的原始值类型被定义为Character,并设置了一些比较常见的ASCII控制字符。
原始值可以时字符串,字符或者任意整型值或浮点型值。每个原始值在枚举声明中必须是唯一的。
note:原始值和关联值是不同的。原始值是在定义枚举时被预先填充的值,对于一个特定的枚举成员,它的原始值始终不变。关联值时创建一个枚举成员的常量或者变量时才设置的值,枚举成员的关联值是可以变化的。
原始值的隐式赋值
1.在使用原始值为整型或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值,Swift将会自动为其赋值。
当使用整数作为原始值时,隐式赋值的值依次递增1.如果第一个枚举成员没有设置原始值,其原始值将为0.
当使用字符串为枚举类型的原始值时,每个枚举成员的隐式原始值为该枚举成员的名称。
2.使用枚举成员的rawValue属性可以访问该枚举成员的原始值:
let value = ASCIIControlCharacter.Tab.rawValue
3.使用原始值初始化枚举实例
如果在定义枚举类型的时候使用了原始值,哪么将会自动获得一个初始化方法,这个方法接受一个叫作rawValue的参数,参数类型即为原始值类型,返回值则式枚举成员或nil。
enum Dirction: Int {
case South
case North
case west
case East
}
let dirction = Dirction(rawValue:2)
if let value = dirction {
print(value)
}
递归枚举
递归枚举是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上indirect来表示该成员可递归。
enum ArithmeticExpression {
case number(Int)
indirect case Addition(ArithmeticExpression,ArithmeticExpression)
indirect case Mulition(ArithmeticExpression,ArithmeticExpression)
}
我们也可以在枚举类型开头加上indirect关键字来表明它的所有成员都是可递归的:
enum ArithmeticExpression {
case number(Int)
indirect case Addition(ArithmeticExpression,ArithmeticExpression)
indirect case Mulition(ArithmeticExpression,ArithmeticExpression)
}
func evalute(expression: ArithmeticExpression) -> Int {
switch expression {
case .number(let value):
return value
case .Addition(let left, let right):
return evalute(left) + evalute(right)
case .Mulition(let left , let right):
return evalute(left) * evalute(right)
}
}
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.Addition(four, five)
let mul = ArithmeticExpression.Mulition(four, five)
evalute(sum)
evalute(mul)