枚舉語(yǔ)法
使用enum關(guān)鍵詞來(lái)創(chuàng)建枚舉并且把它們的整個(gè)定義放在一對(duì)大括號(hào)內(nèi):
enum someEnumeration {
//枚舉定義
case ....
case ....
case ....
}
eg:下面是枚舉表示四個(gè)方向
enum CompassPoint {
case North
case South
case East
case West
}
枚舉中定義的值(如 North,South,Ease和West)是這個(gè)枚舉的成員值(或成員)。我們使用case關(guān)鍵字來(lái)定義一個(gè)新的枚舉成員值。
note:與c和objective-c不同,Swift的枚舉成員在被創(chuàng)建時(shí)不會(huì)被賦予一個(gè)默認(rèn)的整型值。在上面的例子中,North,South,East和west不會(huì)隱式地賦值為0,1,2,和3.相反,這些枚舉成員本身就是完備的值,這些值的類(lèi)型是已經(jīng)明確定義號(hào)的CompassPoint類(lèi)型。
多個(gè)成員值可以出現(xiàn)在同一行上,用逗號(hào)隔開(kāi):
enum CompassPoint {
case North,South,East,West
}
每個(gè)枚舉定義了一個(gè)全新的類(lèi)型。像Swift中其他類(lèi)型一樣,它們的名字必須以一個(gè)大寫(xiě)字母開(kāi)頭。給枚舉類(lèi)型起一個(gè)單數(shù)名字而不是復(fù)數(shù)名字,以便于代碼更加容易理解:
var direction = CompassPoint.South
direction的類(lèi)型可以在它被CompassPoint的某個(gè)值初始化時(shí)推斷出來(lái)。一旦direction被聲明為CompassPoint類(lèi)型,我們就可以使用更短的點(diǎn)語(yǔ)法將其設(shè)置為另一個(gè)CompassPoint的值:
var direction = CompassPoint.South
direction = .West
使用Switch語(yǔ)句匹配枚舉值
我們可以使用Switch語(yǔ)句匹配單個(gè)枚舉值:
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")
}
關(guān)聯(lián)值
1.我們可以定義Swift枚舉來(lái)存儲(chǔ)任意類(lèi)型的關(guān)聯(lián)值,如果需要的話(huà),每個(gè)枚舉成員的關(guān)聯(lián)值類(lèi)型可以各不相同。
2.在Swift中,使用如下方式定義表示兩種商品條形碼的枚舉:
enum Barcode {
case UPCA(Int,Int,Int,Int)
case QRCode(String)
}
定義一個(gè)名為Barcode的枚舉類(lèi)型,它的一個(gè)成員值是具有(Int,Int,Int,Int)類(lèi)型關(guān)聯(lián)值的UPCA,另一個(gè)成員值是具有String類(lèi)型關(guān)聯(lián)值的QRCode。
這個(gè)定義不提供任何Int或String類(lèi)型的關(guān)聯(lián)值,它只是定義了,當(dāng)Barcode常量和變量等于Barcode.UPCA或Barcode.QRCode時(shí),可以存儲(chǔ)的關(guān)聯(lián)值的類(lèi)型。
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)")
}
如果一個(gè)枚舉成員的所有關(guān)聯(lián)值都被提取為常量或者是被提取為變量,為了簡(jiǎn)潔,你可以只在成員名稱(chēng)前標(biāo)注一個(gè) 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)")
}
原始值
作為關(guān)聯(lián)值的替代選擇,枚舉成員可以被默認(rèn)值(稱(chēng)為原始值)預(yù)填充,這些原始值的類(lèi)型必須相同。
enum ASCIIControlCharacter:Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}
枚舉類(lèi)型ASCIIControlCharacter的原始值類(lèi)型被定義為Character,并設(shè)置了一些比較常見(jiàn)的ASCII控制字符。
原始值可以時(shí)字符串,字符或者任意整型值或浮點(diǎn)型值。每個(gè)原始值在枚舉聲明中必須是唯一的。
note:原始值和關(guān)聯(lián)值是不同的。原始值是在定義枚舉時(shí)被預(yù)先填充的值,對(duì)于一個(gè)特定的枚舉成員,它的原始值始終不變。關(guān)聯(lián)值時(shí)創(chuàng)建一個(gè)枚舉成員的常量或者變量時(shí)才設(shè)置的值,枚舉成員的關(guān)聯(lián)值是可以變化的。
原始值的隱式賦值
1.在使用原始值為整型或者字符串類(lèi)型的枚舉時(shí),不需要顯式地為每一個(gè)枚舉成員設(shè)置原始值,Swift將會(huì)自動(dòng)為其賦值。
當(dāng)使用整數(shù)作為原始值時(shí),隱式賦值的值依次遞增1.如果第一個(gè)枚舉成員沒(méi)有設(shè)置原始值,其原始值將為0.
當(dāng)使用字符串為枚舉類(lèi)型的原始值時(shí),每個(gè)枚舉成員的隱式原始值為該枚舉成員的名稱(chēng)。
2.使用枚舉成員的rawValue屬性可以訪問(wèn)該枚舉成員的原始值:
let value = ASCIIControlCharacter.Tab.rawValue
3.使用原始值初始化枚舉實(shí)例
如果在定義枚舉類(lèi)型的時(shí)候使用了原始值,哪么將會(huì)自動(dòng)獲得一個(gè)初始化方法,這個(gè)方法接受一個(gè)叫作rawValue的參數(shù),參數(shù)類(lèi)型即為原始值類(lèi)型,返回值則式枚舉成員或nil。
enum Dirction: Int {
case South
case North
case west
case East
}
let dirction = Dirction(rawValue:2)
if let value = dirction {
print(value)
}
遞歸枚舉
遞歸枚舉是一種枚舉類(lèi)型,它有一個(gè)或多個(gè)枚舉成員使用該枚舉類(lèi)型的實(shí)例作為關(guān)聯(lián)值。使用遞歸枚舉時(shí),編譯器會(huì)插入一個(gè)間接層。你可以在枚舉成員前加上indirect來(lái)表示該成員可遞歸。
enum ArithmeticExpression {
case number(Int)
indirect case Addition(ArithmeticExpression,ArithmeticExpression)
indirect case Mulition(ArithmeticExpression,ArithmeticExpression)
}
我們也可以在枚舉類(lèi)型開(kāi)頭加上indirect關(guān)鍵字來(lái)表明它的所有成員都是可遞歸的:
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)