Swift教程之枚舉

枚舉

C語(yǔ)言中塞关,C枚舉將相關(guān)名稱分配給一組整數(shù)值抬探,而Swift枚舉不必為每個(gè)枚舉值提供一個(gè)值。若為每個(gè)枚舉值提供了值(稱為原始值)帆赢,則該值可以是字符串小压、字符或任何整數(shù)或浮點(diǎn)類型的值。

枚舉還可以指定與每個(gè)枚舉值一起存儲(chǔ)的任何類型的關(guān)聯(lián)值椰于,這與其他語(yǔ)言中的聯(lián)合或變體一樣怠益。

Swift中的枚舉擁有傳統(tǒng)上僅由類支持的許多功能,例如計(jì)算屬性來(lái)提供當(dāng)前枚舉值的附加信息瘾婿,以及實(shí)例方法來(lái)提供與枚舉值的相關(guān)功能蜻牢。

<br />

枚舉語(yǔ)法

使用Enum關(guān)鍵字聲明枚舉:

enum SomeEnumeration {
    // enumeration definition goes here
}

以下是指南針的四個(gè)方向的例子:

enum CompassPoint {
    case north
    case south
    case east
    case west
}

使用case關(guān)鍵字引入新的枚舉情況。

注意

與C和Objective-C不同偏陪,Swift的枚舉值不會(huì)在創(chuàng)建時(shí)分配默認(rèn)整數(shù)值抢呆。上述枚舉值不會(huì)隱式地等于0、1竹挡、2镀娶、3。

多個(gè)case可以寫在一行揪罕,用逗號(hào)隔開(kāi):

enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

每個(gè)枚舉都是一個(gè)全新的類型梯码,像其它類型一樣,名稱以大寫字母開(kāi)頭好啰,且為單數(shù)而非復(fù)數(shù)名稱轩娶。

var directionToHead = CompassPoint.west

使用枚舉類型將某個(gè)枚舉值初始化時(shí),Swift會(huì)推斷其具體枚舉類型框往,下次重新賦值時(shí)鳄抒,可忽略枚舉類型。使用點(diǎn)語(yǔ)法:

directionToHead = .east

<br />

使用Switch語(yǔ)句匹配枚舉值

使用switch語(yǔ)句匹配單個(gè)枚舉值:

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")
}
// Prints "Watch out for penguins"

switch語(yǔ)句必須包括所有沒(méi)有枚舉值椰弊,否則無(wú)法通過(guò)編譯许溅,確保某個(gè)枚舉情況不會(huì)被意外省略。

使用default涵蓋未明確處理的任何枚舉值:

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

<br />

關(guān)聯(lián)值

有時(shí)可以將其他類型的值和枚舉值一起關(guān)聯(lián)起來(lái)秉版,與枚舉值一起存儲(chǔ)贤重,并在每次使用該信息時(shí),該信息會(huì)發(fā)生變化清焕。

以下為攜帶關(guān)聯(lián)值的條形碼枚舉:

enum Barcode {
    case upc(Int, Int, Int, Int)
    case qrCode(String)
}

關(guān)聯(lián)值不提供類型的實(shí)際值并蝗,只提供枚舉值存儲(chǔ)的關(guān)聯(lián)值的類型祭犯。

使用一下任一類型創(chuàng)建枚舉值:

var productBarcode = Barcode.upc(8, 85909, 51226, 3)

productBarcode = .qrCode("ABCDEFGHIJKLMNOP")

使用switch提取關(guān)聯(lián)值:

switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
    print("UPC: \(numberSystem), \(manufacturer), \(product), \(check).")
case .qrCode(let productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

關(guān)聯(lián)值全被提取為常量或變量:

switch productBarcode {
case let .upc(numberSystem, manufacturer, product, check):
    print("UPC : \(numberSystem), \(manufacturer), \(product), \(check).")
case let .qrCode(productCode):
    print("QR code: \(productCode).")
}
// Prints "QR code: ABCDEFGHIJKLMNOP."

<br />

原始值

枚舉值可以使用類型一致的默認(rèn)值(即原始值)填充。

enum ASCIIControlCharacter: Character {
    case tab = "\t"
    case lineFeed = "\n"
    case carriageReturn = "\r"
}

原始值可以是字符串滚停、字符或任何整數(shù)或浮點(diǎn)數(shù)類型沃粗,每個(gè)原始值必須是唯一的。

隱式分配枚舉值

不必為每個(gè)枚舉值顯示分配原始值键畴,Swift會(huì)自動(dòng)分配最盅。

整數(shù)用于原始值時(shí),第一個(gè)枚舉值自動(dòng)設(shè)置為0镰吵,之后遞增1檩禾。

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

上面例子中,Planet.Planet具有顯式原始值1疤祭,其他為隱式枚舉值是在其基礎(chǔ)上遞增1。

字符串作為原始值時(shí)饵婆,每個(gè)枚舉值的隱含原始值是該枚舉值的字符串字面量勺馆。

enum CompassPoint: String {
    case north, south, east, west
}

上面例子中,CompassPoint.south的隱式原始值為“south”侨核,以此類推草穆。

使用枚舉類型的rawValue屬性獲取其枚舉值的原始值:

let earthsOrder = Planet.earth.rawValue
// earthsOrder is 3
 
let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

用原始值初始化枚舉值

若使用原始值類型定義枚舉,枚舉會(huì)自動(dòng)創(chuàng)建一個(gè)初始化器搓译,并可通過(guò)原始值的初始化器創(chuàng)建枚舉的實(shí)例悲柱。

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet is of type Planet? and equals Planet.uranus

然而,并不是所有的原始值都能找到匹配的枚舉值些己,所以原始值初始化器(可失敗的初始化器)總是返回枚舉的可選類型豌鸡,可結(jié)合可選綁定和switch語(yǔ)句處理該可選類型。

let positionToFind = 11
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)")
}
// Prints "There isn't a planet at position 11"

<br />

遞歸枚舉

當(dāng)某個(gè)枚舉值的關(guān)聯(lián)值類型是該枚舉類型時(shí)段标,該枚舉是遞歸枚舉涯冠。

遞歸枚舉有兩種書寫方式:

  1. 在需要遞歸的枚舉值前加上indirect關(guān)鍵字,給部分枚舉值啟用遞歸逼庞。

`

enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

2.在聲明枚舉類型enum關(guān)鍵字前加上indirect關(guān)鍵字蛇更,給所有枚舉值啟用遞歸。

indirect enum ArithmeticExpression {
    case number(Int)
    case addition(ArithmeticExpression, ArithmeticExpression)
    case multiplication(ArithmeticExpression, ArithmeticExpression)
}

創(chuàng)建上述遞歸枚舉實(shí)例:

let five = ArithmeticExpression.number(5)
let four = ArithmeticExpression.number(4)
let sum = ArithmeticExpression.addition(five, four)
let product = ArithmeticExpression.multiplication(sum, ArithmeticExpression.number(2))

將遞歸枚舉封裝成遞歸函數(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))
// Prints "18"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赛糟,一起剝皮案震驚了整個(gè)濱河市派任,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌璧南,老刑警劉巖掌逛,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異穆咐,居然都是意外死亡颤诀,警方通過(guò)查閱死者的電腦和手機(jī)字旭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)崖叫,“玉大人遗淳,你說(shuō)我怎么就攤上這事⌒目” “怎么了屈暗?”我有些...
    開(kāi)封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脂男。 經(jīng)常有香客問(wèn)我养叛,道長(zhǎng),這世上最難降的妖魔是什么宰翅? 我笑而不...
    開(kāi)封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任弃甥,我火速辦了婚禮,結(jié)果婚禮上汁讼,老公的妹妹穿的比我還像新娘淆攻。我一直安慰自己,他們只是感情好嘿架,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布瓶珊。 她就那樣靜靜地躺著,像睡著了一般耸彪。 火紅的嫁衣襯著肌膚如雪伞芹。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天蝉娜,我揣著相機(jī)與錄音唱较,去河邊找鬼。 笑死蜀肘,一個(gè)胖子當(dāng)著我的面吹牛绊汹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扮宠,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼西乖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了坛增?” 一聲冷哼從身側(cè)響起获雕,我...
    開(kāi)封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎收捣,沒(méi)想到半個(gè)月后届案,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡罢艾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年楣颠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尽纽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡童漩,死狀恐怖弄贿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矫膨,我是刑警寧澤差凹,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站侧馅,受9級(jí)特大地震影響危尿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜馁痴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一谊娇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧罗晕,春花似錦邮绿、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)顾腊。三九已至粤铭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杂靶,已是汗流浹背梆惯。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吗垮,地道東北人垛吗。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像烁登,于是被迫代替她去往敵國(guó)和親怯屉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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