枚舉

枚舉

使用enum關鍵詞來創(chuàng)建枚舉并且把它們的整個定義放在一對大括號內(nèi):

enum SomeEnumeration {
// 枚舉定義放在這里
}

下面是用枚舉表示指南針四個方向的例子:

enum CompassPoint {
case North
case South
case East
case West
}”
var directionToHead=CompassPoint.West
//當directionToHead的類型已知時,再次為其賦值可以省略枚舉類型名
directionToHead=.East

枚舉中定義的值(如 North侥涵,South,East和West)是這個枚舉的成員值(或成員)渔隶。你使用case關鍵字來定義一個新的枚舉成員值寸认。

“與 C 和 Objective-C 不同,Swift 的枚舉成員在被創(chuàng)建時不會被賦予一個默認的整型值敬鬓。在上面的CompassPoint例子中淹朋,North,South钉答,East和West不會被隱式地賦值為0础芍,1,2和3数尿。相反仑性,這些枚舉成員本身就是完備的值,這些值的類型是已經(jīng)明確定義好的CompassPoint類型右蹦≌锔耍”

你可以使用switch語句匹配單個枚舉值:

directionToHead = .South
switch directionToHead {
case .North:
    print("Lots of planets have a north")
case .South:
    print("Watch out for penguins")
case .East:
    print("Where the sun rises")
case .West:
    print("Where the skies are blue")
}
// 輸出 "Watch out for penguins”

當不需要匹配每個枚舉成員的時候,你可以提供一個default分支來涵蓋所有未明確處理的枚舉成員:

let somePlanet = Planet.Earth
switch somePlanet {
    case .Earth:
        print("Mostly harmless")
    default:
        print("Not a safe place for humans")
}
// 輸出 "Mostly harmless”

關聯(lián)值

你可以定義 Swift 枚舉來存儲任意類型的關聯(lián)值何陆,如果需要的話晨汹,每個枚舉成員的關聯(lián)值類型可以各不相同。枚舉的這種特性跟其他語言中的可識別聯(lián)合(discriminated unions)甲献,標簽聯(lián)合(tagged unions)宰缤,或者變體(variants)相似。
如下代碼:

enum Barcode {
case UPCA(Int, Int, Int, Int)
case QRCode(String)
}
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)
//“原始的Barcode.UPCA和其整數(shù)關聯(lián)值被新的Barcode.QRCode和其字符串關聯(lián)值所替代”
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

以上代碼可以這么理解:

“定義一個名為Barcode的枚舉類型晃洒,它的一個成員值是具有(Int慨灭,Int,Int球及,Int)類型關聯(lián)值的UPCA氧骤,另一個成員值是具有String類型關聯(lián)值的QRCode。創(chuàng)建了一個名為productBarcode的變量吃引,并將Barcode.UPCA賦值給它筹陵,關聯(lián)的元組值為(8, 85909, 51226, 3)刽锤。”

可以使用一個 switch 語句來檢查不同的條形碼類型朦佩。然而并思,這一次,關聯(lián)值可以被提取出來作為 switch 語句的一部分语稠。你可以在switch的 case 分支代碼中提取每個關聯(lián)值作為一個常量(用let前綴)或者作為一個變量(用var前綴)來使用:

switch productBarcode {
case .UPCA(let numberSystem, let manufacturer, let product, let check):
print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case .QRCode(let productCode):
print("QR code: \(productCode).")
}
// 輸出 "QR code: ABCDEFGHIJKLMNOP."

如果一個枚舉成員的所有關聯(lián)值都被提取為常量宋彼,或者都被提取為變量,為了簡潔仙畦,你可以只在成員名稱前標注一個let或者var:

switch productBarcode {
case let .UPCA(numberSystem, manufacturer, product, check):
print("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).")
case let .QRCode(productCode):
print("QR code: \(productCode).")
}
// 輸出 "QR code: ABCDEFGHIJKLMNOP."

原始值

作為關聯(lián)值的替代選擇输涕,枚舉成員可以被默認值(稱為原始值)預填充,這些原始值的類型必須相同慨畸。

這是一個使用 ASCII 碼作為原始值的枚舉:

//“枚舉類型ASCIIControlCharacter的原始值類型被定義為Character莱坎,并設置了一些比較常見的 ASCII 控制字符”
enum ASCIIControlCharacter: Character {
case Tab = "\t"
case LineFeed = "\n"
case CarriageReturn = "\r"
}

原始值可以是字符串,字符寸士,或者任意整型值或浮點型值檐什。每個原始值在枚舉聲明中必須是唯一的。

注意:原始值和關聯(lián)值是不同的碉京。原始值是在定義枚舉時被預先填充的值厢汹,像上述三個 ASCII 碼。對于一個特定的枚舉成員谐宙,它的原始值始終不變烫葬。關聯(lián)值是創(chuàng)建一個基于枚舉成員的常量或變量時才設置的值,枚舉成員的關聯(lián)值可以變化凡蜻。

原始值得隱式賦值
代碼如下:

// Plant.Mercury的顯式原始值為1搭综,Planet.Venus的隱式原始值為2,依次類推
enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

當使用字符串作為枚舉類型的原始值時划栓,每個枚舉成員的隱式原始值為該枚舉成員的名稱兑巾。

下面的例子是CompassPoint枚舉的細化,使用字符串類型的原始值來表示各個方向的名稱:

enum CompassPoint: String {
case North, South, East, West
}

上面例子中忠荞,CompassPoint.South擁有隱式原始值South蒋歌,依次類推。

使用枚舉成員的rawValue屬性可以訪問該枚舉成員的原始值:

let earthsOrder = Planet.Earth.rawValue
// earthsOrder 值為 3

let sunsetDirection = CompassPoint.West.rawValue
// sunsetDirection 值為 "West”

使用原始值初始化枚舉實例

這個例子利用原始值7創(chuàng)建了枚舉成員Uranus:

enum Planet: Int {
case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 類型為 Planet? 值為 Planet.Uranus

注意:
原始值構造器是一個可失敗構造器委煤,因為并不是每一個原始值都有與之對應的枚舉成員堂油。更多信息請參見可失敗構造器

let positionToFind = 9
if let somePlanet = Planet(rawValue: positionToFind) {
switch somePlanet {
case .Earth:
    print("Mostly harmless")
default:
    print("Not a safe place for humans")
}
} else {
print("There isn't a planet at position \(positionToFind)")
}
// 輸出 "There isn't a planet at position 9

這個例子使用了可選綁定(optional binding),試圖通過原始值9來訪問一個行星碧绞。if let somePlanet = Planet(rawValue: 9)語句創(chuàng)建了一個可選Planet府框,如果可選Planet的值存在,就會賦值給somePlanet讥邻。在這個例子中迫靖,無法檢索到位置為9的行星院峡,所以else分支被執(zhí)行。

遞歸枚舉

以下是難懂的術語解釋:

“遞歸枚舉(recursive enumeration)是一種枚舉類型系宜,它有一個或多個枚舉成員使用該枚舉類型的實例作為關聯(lián)值照激。使用遞歸枚舉時,編譯器會插入一個間接層蜈首。你可以在枚舉成員前加上indirect來表示該成員可遞歸实抡。”

例如欢策,下面的例子中,枚舉類型存儲了簡單的算術表達式:

enum ArithmeticExpression {
case Number(Int)
indirect case Addition(ArithmeticExpression, ArithmeticExpression)
indirect case Multiplication(ArithmeticExpression, ArithmeticExpression)
}

你也可以在枚舉類型開頭加上indirect關鍵字來表明它的所有成員都是可遞歸的:

indirect enum ArithmeticExpression {
case Number(Int)
case Addition(ArithmeticExpression, ArithmeticExpression)
case Multiplication(ArithmeticExpression, ArithmeticExpression)
}

要操作具有遞歸性質(zhì)的數(shù)據(jù)結構赏淌,使用遞歸函數(shù)是一種直截了當?shù)姆绞讲瓤堋@纾旅媸且粋€對算術表達式求值的函數(shù):

func evaluate(expression: ArithmeticExpression) -> Int {
switch expression {
case .Number(let value):
    return value
case .Addition(let left, let right):
    return evaluate(left) + evaluate(right)
case .Multiplication(let left, let right):
    return evaluate(left) * evaluate(right)
}
}

// 計算 (5 + 4) * 2
let five = ArithmeticExpression.Number(5)
let four = ArithmeticExpression.Number(4)
let sum = ArithmeticExpression.Addition(five, four)
let product = ArithmeticExpression.Multiplication(sum, ArithmeticExpression.Number(2))
print(evaluate(product))
// 輸出 "18"

該函數(shù)如果遇到純數(shù)字六水,就直接返回該數(shù)字的值俺孙。如果遇到的是加法或乘法運算,則分別計算左邊表達式和右邊表達式的值掷贾,然后相加或相乘睛榄。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市想帅,隨后出現(xiàn)的幾起案子场靴,更是在濱河造成了極大的恐慌,老刑警劉巖港准,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旨剥,死亡現(xiàn)場離奇詭異,居然都是意外死亡浅缸,警方通過查閱死者的電腦和手機轨帜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衩椒,“玉大人蚌父,你說我怎么就攤上這事∶龋” “怎么了苟弛?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長朝聋。 經(jīng)常有香客問我嗡午,道長,這世上最難降的妖魔是什么冀痕? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任荔睹,我火速辦了婚禮狸演,結果婚禮上,老公的妹妹穿的比我還像新娘僻他。我一直安慰自己宵距,他們只是感情好,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布吨拗。 她就那樣靜靜地躺著满哪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪劝篷。 梳的紋絲不亂的頭發(fā)上哨鸭,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音娇妓,去河邊找鬼像鸡。 笑死,一個胖子當著我的面吹牛哈恰,可吹牛的內(nèi)容都是我干的只估。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼着绷,長吁一口氣:“原來是場噩夢啊……” “哼蛔钙!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起荠医,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤吁脱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后子漩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豫喧,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年幢泼,在試婚紗的時候發(fā)現(xiàn)自己被綠了紧显。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡缕棵,死狀恐怖孵班,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情招驴,我是刑警寧澤篙程,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站别厘,受9級特大地震影響虱饿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一氮发、第九天 我趴在偏房一處隱蔽的房頂上張望渴肉。 院中可真熱鬧,春花似錦爽冕、人聲如沸仇祭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乌奇。三九已至,卻和暖如春眯娱,著一層夾襖步出監(jiān)牢的瞬間礁苗,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工困乒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留寂屏,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓娜搂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親吱抚。 傳聞我的和親對象是個殘疾皇子百宇,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 本章將會介紹 閉包表達式尾隨閉包值捕獲閉包是引用類型逃逸閉包自動閉包枚舉語法使用Switch語句匹配枚舉值關聯(lián)值原...
    寒橋閱讀 1,559評論 0 3
  • 枚舉為一組相關的值定義了一個共同的類型携御,使你可以在你的代碼中以類型安全的方式來使用這些值。 如果你熟悉 C 語言既绕,...
    雨影閱讀 349評論 0 0
  • 枚舉為一組相關的值定義了一個共同的類型啄刹,使得可以在代碼中以類型安全的方式來使用這些值。 如果熟悉 C 語言凄贩,會知道...
    窮人家的孩紙閱讀 854評論 1 4
  • //枚舉//“枚舉為一組相關的值定義了一個共同的類型誓军,使你可以在你的代碼中以 類型安全 的方式來使用這些...
    你weixiao的時候很美閱讀 417評論 0 0
  • 你來自哪里,我想認識你 我是一個怪人疲扎,沒有朋友來看我 我很孤獨昵时,你會找我嗎? 他們會吃人 我一直在躲避 你也要小心...
    導演張升志閱讀 133評論 0 0