枚舉
定義和使用
使用enum
關(guān)鍵詞來創(chuàng)建枚舉并且把它們的整個(gè)定義放在一對(duì)大括號(hào)內(nèi),使用case
關(guān)鍵字來定義一個(gè)新的枚舉成員值。
enum CompassPoint {
case north
case south
case east
case west
}
使用
let direction: CompassPoint = .north
使用Switch
語句匹配枚舉值
case .north:
print("direction is north")
case .south:
print("direction is south")
case .east:
print("direction is east")
case .west:
print("direction is west")
}
關(guān)聯(lián)值
你可以定義Swift
枚舉來存儲(chǔ)任意類型的關(guān)聯(lián)值建邓,如果需要的話,每個(gè)枚舉成員的關(guān)聯(lián)值類型可以各不相同尔许。枚舉的這種特性跟其他語言中的可識(shí)別聯(lián)合discriminated unions
睛低,標(biāo)簽聯(lián)合tagged unions
,或者變體variants
相似磕昼。
定義一個(gè)名為Barcode
的枚舉類型卷雕,它的一個(gè)成員值是具有(Int,Int票从,Int漫雕,Int)
類型關(guān)聯(lián)值的upc
,另一個(gè)成員值是具有String
類型關(guān)聯(lián)值的qrCode
峰鄙。
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
然后可以使用任意一種條形碼類型創(chuàng)建新的條形碼浸间,例如:
var productBarcode = Barcode.upc(8, 0085, 2106, 3)
同一個(gè)商品可以被分配一個(gè)不同類型的條形碼,例如:
productBarcode = Barcode.qrCode("ABCDEFGHIJKLMNOP")
原始值
枚舉成員可以被默認(rèn)值(稱為原始值)預(yù)填充吟榴,這些原始值的類型必須相同魁蒜。
enum ASCIIControlCharacter: Character {
case tab = "\t"
case lineFeed = "\n"
case carriageReturn = "\r"
}
原始值的隱式賦值
在使用原始值為整數(shù)或者字符串類型的枚舉時(shí),不需要顯式地為每一個(gè)枚舉成員設(shè)置原始值吩翻,Swift
將會(huì)自動(dòng)為你賦值兜看。
enum Planet: Int {
case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}
Plant.mercury
的顯式原始值為1
,Planet.venus
的隱式原始值為2
狭瞎,依次類推细移。
使用原始值初始化枚舉實(shí)例
如果在定義枚舉類型的時(shí)候使用了原始值,那么將會(huì)自動(dòng)獲得一個(gè)初始化方法熊锭,這個(gè)方法接收一個(gè)叫做rawValue
的參數(shù)弧轧,參數(shù)類型即為原始值類型缔刹,返回值則是枚舉成員或nil
。你可以使用這個(gè)初始化方法來創(chuàng)建一個(gè)新的枚舉實(shí)例劣针。
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 類型為 Planet? 值為 Planet.uranus
let impossiblePlanet = Planet(rawValue: 11)
print(impossiblePlanet as Any) // nil
遞歸枚舉
遞歸枚舉是一種枚舉類型校镐,它有一個(gè)或多個(gè)枚舉成員使用該枚舉類型的實(shí)例作為關(guān)聯(lián)值。使用遞歸枚舉時(shí)捺典,編譯器會(huì)插入一個(gè)間接層鸟廓。你可以在枚舉成員前加上indirect
來表示該成員可遞歸。
例如襟己,下面的例子中引谜,枚舉類型存儲(chǔ)了簡單的算術(shù)表達(dá)式:
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
你也可以在枚舉類型開頭加上indirect
關(guān)鍵字來表明它的所有成員都是可遞歸的:
indirect enum ArithmeticExpression {
case number(Int)
case addition(ArithmeticExpression, ArithmeticExpression)
case multiplication(ArithmeticExpression, ArithmeticExpression)
}
上面定義的枚舉類型可以存儲(chǔ)三種算術(shù)表達(dá)式:純數(shù)字、兩個(gè)表達(dá)式相加擎浴、兩個(gè)表達(dá)式相乘员咽。
let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))
要操作具有遞歸性質(zhì)的數(shù)據(jù)結(jié)構(gòu),使用遞歸函數(shù)是一種直截了當(dāng)?shù)姆绞街ぁ@绫词遥旅媸且粋€(gè)對(duì)算術(shù)表達(dá)式求值的函數(shù):
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"
該函數(shù)如果遇到純數(shù)字,就直接返回該數(shù)字的值仿吞。如果遇到的是加法或乘法運(yùn)算滑频,則分別計(jì)算左邊表達(dá)式和右邊表達(dá)式的值,然后相加或相乘唤冈。