Swift8-枚举Enumerations
枚举语法、使用Switch语句匹配枚举值、关联值、原始值、递归枚举。
枚举为一组相关的值定义了一个共同的类型,使你可以在你的代码中以类型安全的方式来使用这些值。
C/C++中枚举为一组整型值分配相关联的名称。Swift中的枚举更加灵活,不必给每一个枚举成员提供一个值。如果给枚举成员提供一个值(称为“原始”值),则该值的类型可以是字符串、字符、或是一个整型值或浮点数。
枚举成员可以指定任何类型的关联值存储到枚举成员中,就像其它语言中的联合体(union)和变体(variants)。可以在一个枚举中定义一组相关的枚举成员,每一个枚举成员都可以有适当类型的关联值。
Swift中,枚举类型是一等类型。采用了很多在传统上只被类所支持的特性,例如计算属性(用于提供枚举值的附加信息)、实例方法(用于提供和枚举值相关联的功能)。枚举也可以定义构造函数来提供一个初始值;可以在原始实现的基础上扩展它们的功能;还可以遵循协议来提供标准的功能。
枚举语法:
使用enum关键词来创建枚举并且把它们的整个定义放在一对大括号内:
enum SomeEnumeration{
//枚举定义放在这里
}
enum CompassPoint{
case north
case south
case east
case west
}
使用case关键字来定义一个新的枚举成员值。
Swift枚举成员在被创建时不会被赋予一个默认的整型值。上面的north,south,east,west等不会被隐式赋值为0,1,2,3.相反,这些枚举成员本身就是完备的值,这些值的类型是已经明确定义好的CompassPoint类型。
多个成员值可以出现在同一行上,用逗号隔开:
enum Planet{
case mercury,venus,earth,mars,jupiter,saturn,uranus,neptune
}
每个枚举定义了一个全新的类型。
var aa=CompassPoint.west
aa的类型可以在它被枚举CompassPoint的某个值初始化时推断出来。一旦aa被声明为CompassPoint类型,就可以使用更简洁的点语法将其设置为另一个CompassPoint的值:
aa=.east
当aa类型已知时,再次为其赋值可以省略枚举类型名。
使用switch语句匹配枚举值:
switch aa{
case .west:...
case .east:...
...
default:break
}
switch语句必须穷举所有情况。如果忽略了枚举中某个取值,代码将在编译时期出错。
如果不需要匹配每个枚举成员,可用default分支来涵盖所有未明确处理的枚举成员。
关联值:
把其他类型的关联值和成员值一起存储起来会很有用。这能让你连同成员值一起存储额外的自定义信息,并且每次在代码中使用该枚举成员时,还可以修改这个关联值。
可以定义Swift枚举来存储任意类型的关联值,每个枚举成员的关联值类型可以各不相同。
enum Barcode{
case upc(Int,Int,Int,Int)
case qrCode(String)
}
上述定义了一个名为Barcode的枚举类型,它的一个成员值是具有(Int,Int,Int,Int)类型关联值的upc,另一个成员值是具有String类型关联值的qrCode。
var bb=Barcode.upc(1,2,3,4)
枚举成员可有多个,赋予一个变量/常量上的只有其中某一个。
case .upc(let a,let b,let c,let d)
case let .upc(a,b,c,d)
原始值:
枚举成员可以被默认值预填充,称为原始值,这些原始值的类型必须相同。
enum Sheep:String{
case xyy="xyy"
case lyy="lyy"
}
原始值可以是字符串、字符、或者任意整型值或浮点型值。每个原始值在枚举声明中必须是唯一的。
原始值的隐式赋值:
在使用原始值为整数或者字符串类型的枚举时,不需要显式地为每一个枚举成员设置原始值,Swift将会自动为你赋值。
例如,当使用整数作为原始值时,隐式赋值的值依次递增1.如果第一个枚举成员没有设置原始值,其原始值将为0。
使用枚举成员的rawValue属性可以访问枚举成员的原始值。
没有原始值的枚举赋值的常量/变量,访问rawValue会编译出错。
当字符串作为枚举类型的原始值时,每个枚举成员的隐式原始值为该枚举成员的名称。
enum point:String{
case north,south,east,west
}
north的隐式原始值是"north",后面以此类推。
使用原始值初始化枚举实例:
如果在定义枚举类型的时候使用了原始值,那么将会自动获得一个初始化方法,这个方法接收一个叫做rawValue的参数,参数类型即为原始值类型,返回值则是枚举成员或nil。
let possiblePlanet=Planet(rawValue:7)
这个方法获得的是一个可选值。Optional(xxx)。上例中是Planet?类型。无传入原始值对应的枚举成员是返回nil。
递归枚举:
递归枚举是一种枚举类型,它有一个或多个枚举成员使用该枚举类型的实例作为关联值。使用递归枚举时,编译器会插入一个间接层。可以在枚举成员前加上indirect来表示该成员可递归。
也可以在枚举类型开头加上indirect关键字来表明它的所有成员都是可递归的。
enum aa{
case a(Int)
indirect case b(aa)
indirect case c(aa,aa)
}
indirect enum bb{
case a(Int)
case b(bb)
}
要操作具有递归性质的数据结构,使用递归函数是一种直截了当的方式。
func evaluate(_ expression: aa)->Int{
switch expression{
case let .a(value):
return value
case let .b(value):
return evaluate(value)+evaluate(value)
case let .c(vvv,mmm):
return evaluate(vvv)*evaluate(mmm)
}
}
let four=aa.a(4) //声明两个a枚举类型的aa成员常量
let db=aa.b(four) //
let prod=aa.c(db,four)
evaluate(four) //返回结果4 直接返回值
evaluate(db) //返回结果8 evaluate-> evaluate+evaluate
evaluate(prod) //返回结果48 evaluate-> evaluate*evaluate-> (evaluate+evaluate)*evaluate