- 枚举简单的说也是一种数据类型,只不过是这种数据类型只包含自定义的特定数据,它是一组有共同特性的数据的集合。
- Swift 的枚举类似于 Objective C 和 C 的结构,枚举的功能为:
枚举也可以定义构造函数(initializers)来提供一个初始成员值;可以在原始的实现基础上扩展它们的功能。
它声明在类中,可以通过实例化类来访问它的值。
可以遵守协议(protocols)来提供标准的功能。
枚举语法
-
使用
enum
关键词来创建枚举并且把它们的整个定义放在一对大括号内,使用case
关键字来定义一个新的枚举成员值。 -
给枚举类型起一个单数名字而不是复数名字。
enum SomeEnumeration { // 枚举定义放在这里 } // north,south,east 和 west 不会被隐式地赋值为 0,1,2 和 3 // 这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的 CompassPoint 类型。 enum CompassPoint { case north case south case east case west } // 多个成员值可以出现在同一行上,用逗号隔开: enum Planet { case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune }
使用 Switch 语句匹配枚举值
- 可以使用
switch
语句匹配单个枚举值:directionToHead = .south switch directionToHead { case .north: print("Lots of planets have a north") case .south: print("Watch out for penguins") case .east: print("Where the sun rises") case .west: print("Where the skies are blue") } // 打印“Watch out for penguins” // 不需要匹配每个枚举成员的时候,你可以提供一个 default 分支来涵盖所有未明确处理的枚举成员 let somePlanet = Planet.earth switch somePlanet { case .earth: print("Mostly harmless") default: print("Not a safe place for humans") } // 打印“Mostly harmless”
枚举成员的遍历
-
枚举遵循
CaseIterable
协议。Swift 会生成一个allCases
属性,用于表示一个包含枚举所有成员的集合。enum Beverage: CaseIterable { case coffee, tea, juice } let numberOfChoices = Beverage.allCases.count print("\(numberOfChoices) beverages available") // 打印“3 beverages available” for beverage in Beverage.allCases { print(beverage) }
关联值
-
在
Swift
中如果想要表示复杂的含义,可以在枚举中关联更多的信息。 -
可以定义 Swift 枚举来存储任意类型的关联值,如果需要的话,每个枚举成员的关联值类型可以各不相同。枚举的这种特性跟其他语言中的可识别联合(discriminated unions),标签联合(tagged unions),或者变体(variants)相似。
// 需要有一个形状的枚举,里面有圆形和矩形。圆形有半径,矩形有长宽 // 其中括号中的radius以及width和height就是关联值 enum Shape{ case circle(radius: Double) case rectangle(width: Int, height: Int) } // 关联值枚举的模式匹配 let shape = Shape.circle(radius: 10.0) // 不关心关联值 switch shape { case .circle: print("the shape is circle") case .rectangle: print("the shape is rectangle") } // 关心关联值 // 每个case中都使用了let或者var,这里因为要使用关联值,所以需要使用let声明一下 switch shape{ case let .circle(radius): print("circle radius: \(radius)") case .rectangle(let width, var height): height += 1 print("rectangle width: \(width) height: \(height)") }
原始值
-
原始值可以是字符串,字符,或者任何整型值或浮点型值。每个原始值在它的枚举声明中必须是唯一的。
-
在原始值为整数的枚举时,不需要显式的为每一个成员赋值,Swift会自动为你赋值。
// 当使用整数作为原始值时,隐式赋值的值依次递增1。如果第一个值没有被赋初值,将会被自动置为0。 enum Month: Int { case January = 1, February, March, April, May, June, July, August, September, October, November, December } let yearMonth = Month.May.rawValue print("数字月份为: \(yearMonth)。")
使用原始值初始化枚举实例
-
如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做
rawValue
的参数,参数类型即为原始值类型,返回值则是枚举成员或nil
。你可以使用这个初始化方法来创建一个新的枚举实例。// 利用原始值 7 创建了枚举成员 Uranus: let possiblePlanet = Planet(rawValue: 7) // possiblePlanet 类型为 Planet? 值为 Planet.uranus
递归枚举
-
递归枚举是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。你可以在枚举成员前加上
indirect
来表示该成员可递归。enum ArithmeticExpression { case number(Int) indirect case addition(ArithmeticExpression, ArithmeticExpression) indirect case multiplication(ArithmeticExpression, ArithmeticExpression) } // 你也可以在枚举类型开头加上 indirect 关键字来表明它的所有成员都是可递归的: // 定义的枚举类型可以存储三种算术表达式:纯数字、两个表达式相加、两个表达式相乘。枚举成员 addition 和 multiplication 的关联值也是算术表达式——这些关联值使得嵌套表达式成为可能。 indirect enum ArithmeticExpression { case number(Int) case addition(ArithmeticExpression, ArithmeticExpression) case multiplication(ArithmeticExpression, ArithmeticExpression) } // 使用 ArithmeticExpression 这个递归枚举创建表达式 (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)) // 算术表达式求值的函数 // 该函数如果遇到纯数字,就直接返回该数字的值。如果遇到的是加法或乘法运算,则分别计算左边表达式和右边表达式的值,然后相加或相乘。 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”
网友评论