枚举是啥我就不多说了。
Swift中的枚举更灵活,并且不必给每个枚举成员赋值。如果给枚举成员赋值(称为『原始』值),这个值可以是字符串、字符、整型或者浮点型。
此外,枚举成员可以指定任意类型的关联值存储到枚举成员中,就像其他语言中的联合体(unions)和变体(variants)。每一个枚举成员都可以有适当类型的关联值。
在 Swift 中,枚举类型是一等(first-class)类型。它们采用了很多在传统上只被类(class)所支持的特性,例如计算型属性(computed properties),用于提供枚举值的附加信息,实例方法(instance methods),用于提供和枚举值相关联的功能。枚举也可以定义构造函数(initializers)来提供一个初始值;可以在原始实现的基础上扩展它们的功能;还可以遵守协议(protocols)来提供标准的功能。
原谅上面这两段话,我是copy的。。
枚举语法(Enumeration Syntax)
先来个简单的枚举:
enum CompassPoint {
case north
case south
case east
case west
}
注意
与C和OC不同,Swift的枚举在创建的时候是不会赋一个默认的整型值的。相反,在上面的例子中,枚举的每个成员的值就他们本身,并且类型就是 CompassPoint 类型。
多个成员出现在一行的时候,用逗号隔开:
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
每个枚举都是一个新的类型,所以和Swift中的其他类型一样,首字母大写。并且最好用单数名字而不是复数名字:
var directionToHead = CompassPoint.north
上面🌰中,directionToHead被推断为CompassPoint类型,所以当你在改变值的时候可以使用更简短的点语法:
directionToHead = .south
用Swift语句匹配枚举值(Matching Enumeration Values with a Switch Statement)
关联值(Associated Values)
在Swift的枚举中,可以给每个枚举成员设置关联值,各个成员之间的关联值的类型可以不相同,并且在使用的时候可以修改关联值。枚举的这种特性跟其他语言中的可识别联合(discriminated unions),标签联合(tagged unions),或者变体(variants)相似。
举个🌰,现在有一个厂商,它有两种条形码。一种是UPC-A格式的一维码,是由四个部分组成的:『数字系统』(1位)、『厂商代码』(5位)、『产品代码』(5位)、『检查位』(1位):
另一种就是 QR 码格式的二维码,可以存储最多 2953个字符的字符串:
所以这个枚举就可以这么定义:
enum Barcode {
case upc(Int, Int, Int, Int)
case qrcode(String)
}
这样定义了之后不会赋任何值,只是声明了类型。但是当Barcode
常量和变量等于 Barcode.UPCA 或 Barcode.QRCode 时,可以存储的关联值的类型:
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrcode("ABCDEFGHIJKLMNOP")
这样的情况下,productBarcode的值就会被后面的这个替换掉。
如果每个关联值都被提取成常亮(变量),为了简洁,只需要在成员名称前面标注 let(var) 就可以了:
原始值(Raw Values)
上面的🌰讲了一下怎么关联不同的值,接下来要说的就是怎么设置默认值(原始值),但是设置原始值,每个成员的类型必须一致:
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
原始值可以是字符串、字符,也可以是任意值的整型或浮点型,但是每个成员的值必须是唯一的!
注意
原始值和关联值是不同的。原始值就是枚举定义时预先填充的值,而关联值是一个基于枚举类型的常量(变量)才设置的值。最显著的区别就是原始值设置之后就不会改变了,但是关联值是会在之后的调用中改变的。
原始值的隐式赋值(Implicitly Assigned Raw Values)
当设置用字符串和整型设置原始值的时候,不必给每一个成员都设置一遍,Swift会自动设置。
举个🌰,当设置整型的时候,隐式赋值的值会一次增加1,如果第一个枚举成员没有设置原始值,其原始值为0:
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
当设置的是字符串的时候,隐式赋值就是没给成员的名字:
用原始值初始化枚举实例(Initializing from a Raw Value)
文字没整理好怎么翻译,直接上🌰:
这个🌰中不是所有的rawValue都可以找到一个对应的枚举成员,也就是说用这种方法创建的枚举实例返回的类型是一个可选类型。再通俗点就是这么初始化实例有可能返回nil:
递归枚举(Recursive Enumerations)
递归枚举也是枚举的一个类型,它是由一个或者多个枚举成员使用该枚举类型的实例作为关联值。在枚举成员前加上 indirect 关键字来表示该成员可递归,同时告诉编译器插入一个间接层(layer of indirection):
也可以在枚举前面加上 indirect 来表明所有的成员都是可以递归的:
下面的🌰展示了使用ArithmeticExpression这个递归枚举计算表达式(5 + 4) * 2: