枚举为一种相关值定义了一个通用类型,从而可以让你在代码中类型安全的操作这些值。
Swift中的枚举很灵活,不需要给每一个枚举中的成员都提供值。如果一个值(所谓 原时值) 要被提供给每一个枚举成员,那么这个值可以是字符串 字符 任意的整数值 或者浮点类型。
而且 枚举成员可以指定任意类型的值来与不痛的成员值关联。你可以定义一组相关成员的合集作为枚举的一部分,每一个成员都可以有不同类型的值的合集与其关联。
Swift 中的枚举是具有自己权限的一类类型。它们使用了许多一般只被类所支持的特性,例如计算属性用来提供关于枚举当前值的额外信息,并且实例方法用来提供与枚举表示的值相关的功能。枚举同样也能够定义初始化器来初始化成员值;而且能够遵循协议来提供标准功能。
枚举语法
使用enum关键字来定义一个枚举,然后将所有的定义内容放在一个大括号{}中
enum SomeEnumeration { //枚举成员 }
指南针的四个主要方向的例子
enum CompassPoint { case north case south case east case west }
在一个枚举中定义的值(比如: north, south, east和 west)就是枚举的成员值(或成员) case关键字则明确了要定义成员值。
注意:
不像 C 和 Objective-C 那样,Swift 的枚举成员在被创建时不会分配一个默认的整数值。在上文的 CompassPoint例子中, north, south, east和 west并不代表 0, 1, 2和 3。而相反,不同的枚举成员在它们自己的权限中都是完全合格的值,并且是一个在 CompassPoint中被显式定义的类型。
多个成员值可以出现在同一行中,要用逗号隔开
enum Planet { case mercury,venus,earth, mars, jupiter, saturn, uranus, neptune }
每个枚举都定义了一个全新的类型。正如 Swift 中其它的类型那样,它们的名称(例如: CompassPoint和 Planet)需要首字母大写。给枚举类型起一个单数的而不是复数的名字,从而使得它们能够顾名思义:
var directionToHead = CompassPoint.west
当与 CompassPoint中可用的某一值一同初始化时 directionToHead的类型会被推断出来。一旦 directionToHead以 CompassPoint类型被声明,你就可以用一个点语法把它设定成不同的 CompassPoint值:
directionToHead = .east
directionToHead的类型是已知的,所以当设定它的值时你可以不用写类型。这样做可以使得你在操作确定类型的枚举时让代码非常易读。
使用Switch语句来匹配枚举值
var directionToHead = CompassPoint.west directionToHead = .east switch directionToHead { case .north: print("北方") case .south: print("南方") case .east: print("东方") default: print("西方") }
switch 语句应该是全覆盖的 如果 .west的 case被省略了,那么代码将不能编译,因为这时表明它并没有覆盖 CompassPoint的所有成员。要求覆盖所有枚举成员是因为这样可以保证枚举成员不会意外的被漏掉。
关联值
关联值是将额外信息附加到enum case 中的一种极好的方式,打个比方,你正在开发一款交易引擎,可能存在买和卖两种不同的交易类型。除此之外每手交易还需要指定明确的股票名和交易数量:
enum Trade { case Buy case Sell } func trade(tradeType:Trade,stock:String,amount:Int){ }
然而股票的价值和数量显然从属于交易,让他们作为毒瘤的参数显得模棱两可。这个时候枚举的关联值就可以很好的解决这个问题
enum Trade { case Buy(stock:String,amount:Int) case Sell(stock:String,amount:Int) } func trade(tradeType:Trade){ }
enum Trade { case Buy(stock:String,amount:Int) case Sell(stock:String,amount:Int) } func createTrad(stockName:String,stockCount:Int) ->Trade { if stockCount > 1000 { return .Buy(stock: stockName, amount: stockCount) }else { return .Sell(stock: stockName, amount: stockCount) } } let result = createTrad(stockName: "腾讯", stockCount: 100) switch result { case let .Buy(stockName,stockCount): print("(stockName) and (stockCount)") case let .Sell(stockName,stockCount): print("(stockName) and (stockCount)") } //关联值 也可以有多个 enum Barcode { case UPCA(chang:Int,kuan:Int,gao:Int) case QRcode(String) } func createQRcode(first:Int,second:Int,Third:Int,Info:String)->Barcode { if first < second && Third > second { return .UPCA(chang: first, kuan: second, gao: Third) }else { return .QRcode(Info) } }
原始值
为每一个枚举的成员分配一个原始值
enum Movement:Int{ case Left = 0 case Right = 1 case Top = 2 case Bottom = 3 } //同样你可以与字符串一一对应 enum House:String { case Baratheon = "Ours is the Fury" case Greyjoy = "We Do Not Sow" case Martell = "Unbowed, Unbent, Unbroken" case Stark = "Winter is Coming" case Tully = "Family, Duty, Honor" case Tyrell = "Growing Strong" } // 或者float double都可以(同时注意枚举中的花式unicode) enum Constants: Double { case π = 3.14159 case e = 2.71828 case φ = 1.61803398874 case λ = 1.30357 }
隐式指定的原始值
对于String和Int类型来说,你甚至可以忽略枚举中的case赋值,Swift编译器也能正常工作
enum Planent:Int { case Mercury = 1,venus,Earth,Mars, Jupiter, Saturn, Uranus, Neptune } //对于绑定原始值为字符串类型的来说 如果没有明确写出 默认原始值是本身 enum CompassPointSecond:String { case North,South,East,West } var plaent = Planent.Mars plaent.rawValue//4 var point = CompassPointSecond.South point.rawValue//"South"
从原始值初始化
//这样获取的是可选值 使用的时候注意解包 let plaent = Planent(rawValue:3)// .Earth if let plaent = plaent { plaent.rawValue//3 } let point = CompassPointSecond(rawValue:"South")//.South if let south = point { south.rawValue // "South" }