在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ 枚舉(Enumerations)
方法 - Methods
關于 Swift
下標腳本(Subscripts)
類和結(jié)構(gòu)體
類型轉(zhuǎn)換(Type Casting)
控制流
析構(gòu)過程(Deinitialization)
集合類型 (Collection Types)
構(gòu)造過程(Initialization)
Optional Chaining
枚舉(Enumerations)
自動引用計數(shù)
繼承(Inheritance)
擴展(Extensions)
泛型
字符串和字符(Strings and Characters)
函數(shù)(Functions)
高級運算符
訪問控制
基本運算符
嵌套類型
閉包(Closures)
協(xié)議
屬性 (Properties)

枚舉(Enumerations)

枚舉定義了一個通用類型的一組相關的值,使你可以在你的代碼中以一個安全的方式來使用這些值。

如果你熟悉 C 語言,你就會知道,在 C 語言中枚舉指定相關名稱為一組整型值。Swift 中的枚舉更加靈活,不必給每一個枚舉成員提供一個值。如果一個值(被認為是“原始”值)被提供給每個枚舉成員,則該值可以是一個字符串,一個字符,或是一個整型值或浮點值。

此外,枚舉成員可以指定任何類型的相關值存儲到枚舉成員值中,就像其他語言中的聯(lián)合體(unions)和變體(variants)。你可以定義一組通用的相關成員作為枚舉的一部分,每一組都有不同的一組與它相關的適當類型的數(shù)值。

在 Swift 中,枚舉類型是一等(first-class)類型。它們采用了很多傳統(tǒng)上只被類(class)所支持的特征,例如計算型屬性(computed properties),用于提供關于枚舉當前值的附加信息,?實例方法(instance methods),用于提供和枚舉所代表的值相關聯(lián)的功能。枚舉也可以定義構(gòu)造函數(shù)(initializers)來提供一個初始成員值;可以在原始的實現(xiàn)基礎上擴展它們的功能;可以遵守協(xié)議(protocols)來提供標準的功能。

欲了解更多相關功能,請參見屬性(Properties),方法(Methods),構(gòu)造過程(Initialization),擴展(Extensions)協(xié)議(Protocols)。

枚舉語法

使用enum關鍵詞并且把它們的整個定義放在一對大括號內(nèi):

    enum SomeEnumeration {
    // enumeration definition goes here
    }

以下是指南針四個方向的一個例子:

    enum CompassPoint {
        case North
        case South
        case East
        case West
    }

一個枚舉中被定義的值(例如 North,South,EastWest)是枚舉的成員值(或者成員)。case關鍵詞表明新的一行成員值將被定義。

注意:
不像 C 和 Objective-C 一樣,Swift 的枚舉成員在被創(chuàng)建時不會被賦予一個默認的整數(shù)值。在上面的CompassPoints例子中,North,South,EastWest不是隱式的等于0,1,23。相反的,這些不同的枚舉成員在CompassPoint的一種顯示定義中擁有各自不同的值。

多個成員值可以出現(xiàn)在同一行上,用逗號隔開:

    enum Planet {
        case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
    }

每個枚舉定義了一個全新的類型。像 Swift 中其他類型一樣,它們的名字(例如CompassPointPlanet)必須以一個大寫字母開頭。給枚舉類型起一個單數(shù)名字而不是復數(shù)名字,以便于讀起來更加容易理解:

    var directionToHead = CompassPoint.West

directionToHead的類型被推斷當它被CompassPoint的一個可能值初始化。一旦directionToHead被聲明為一個CompassPoint,你可以使用更短的點(.)語法將其設置為另一個CompassPoint的值:

    directionToHead = .East

directionToHead的類型已知時,當設定它的值時,你可以不再寫類型名。使用顯式類型的枚舉值可以讓代碼具有更好的可讀性。

匹配枚舉值和Switch語句

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

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

你可以如此理解這段代碼:

“考慮directionToHead的值。當它等于.North,打印“Lots of planets have a north”。當它等于.South,打印“Watch out for penguins”。”

等等依次類推。

正如在控制流(Control Flow)中介紹,當考慮一個枚舉的成員們時,一個switch語句必須全面。如果忽略了.West這種情況,上面那段代碼將無法通過編譯,因為它沒有考慮到CompassPoint的全部成員。全面性的要求確保了枚舉成員不會被意外遺漏。

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

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

相關值(Associated Values)

上一小節(jié)的例子演示了一個枚舉的成員是如何被定義(分類)的。你可以為Planet.Earth設置一個常量或則變量,并且在之后查看這個值。不管怎樣,如果有時候能夠把其他類型的相關值和成員值一起存儲起來會很有用。這能讓你存儲成員值之外的自定義信息,并且當你每次在代碼中使用該成員時允許這個信息產(chǎn)生變化。

你可以定義 Swift 的枚舉存儲任何類型的相關值,如果需要的話,每個成員的數(shù)據(jù)類型可以是各不相同的。枚舉的這種特性跟其他語言中的可辨識聯(lián)合(discriminated unions),標簽聯(lián)合(tagged unions),或者變體(variants)相似。

例如,假設一個庫存跟蹤系統(tǒng)需要利用兩種不同類型的條形碼來跟蹤商品。有些商品上標有 UPC-A 格式的一維碼,它使用數(shù)字 0 到 9。每一個條形碼都有一個代表“數(shù)字系統(tǒng)”的數(shù)字,該數(shù)字后接 10 個代表“標識符”的數(shù)字。最后一個數(shù)字是“檢查”位,用來驗證代碼是否被正確掃描:

![Image of Enumerations_1.png]
(images/Enumerations_1.png)

其他商品上標有 QR 碼格式的二維碼,它可以使用任何 ISO8859-1 字符,并且可以編碼一個最多擁有 2,953 字符的字符串:

![Image of Enumerations_2.png]
(images/Enumerations_2.png)

對于庫存跟蹤系統(tǒng)來說,能夠把 UPC-A 碼作為三個整型值的元組,和把 QR 碼作為一個任何長度的字符串存儲起來是方便的。

在 Swift 中,用來定義兩種商品條碼的枚舉是這樣子的:

    enum Barcode {
        case UPCA(Int, Int, Int)
        case QRCode(String)
    }

以上代碼可以這么理解:

“定義一個名為Barcode的枚舉類型,它可以是UPCA的一個相關值(IntInt,Int),或者QRCode的一個字符串類型(String)相關值?!?/p>

這個定義不提供任何IntString的實際值,它只是定義了,當Barcode常量和變量等于Barcode.UPCABarcode.QRCode時,相關值的類型。

然后可以使用任何一種條碼類型創(chuàng)建新的條碼,如:

    var productBarcode = Barcode.UPCA(8, 85909_51226, 3)

以上例子創(chuàng)建了一個名為productBarcode的新變量,并且賦給它一個Barcode.UPCA的相關元組值(8, 8590951226, 3)。提供的“標識符”值在整數(shù)字中有一個下劃線,使其便于閱讀條形碼。

同一個商品可以被分配給一個不同類型的條形碼,如:

    productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

這時,原始的Barcode.UPCA和其整數(shù)值被新的Barcode.QRCode和其字符串值所替代。條形碼的常量和變量可以存儲一個.UPCA或者一個.QRCode(連同它的相關值),但是在任何指定時間只能存儲其中之一。

像以前那樣,不同的條形碼類型可以使用一個 switch 語句來檢查,然而這次相關值可以被提取作為 switch 語句的一部分。你可以在switch的 case 分支代碼中提取每個相關值作為一個常量(用let前綴)或者作為一個變量(用var前綴)來使用:

    switch productBarcode {
    case .UPCA(let numberSystem, let identifier, let check):
        println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
    case .QRCode(let productCode):
        println("QR code with value of \(productCode).")
    }
    // 輸出 "QR code with value of ABCDEFGHIJKLMNOP.”

如果一個枚舉成員的所有相關值被提取為常量,或者它們?nèi)勘惶崛樽兞?,為了簡潔,你可以只放置一個var或者let標注在成員名稱前:

    switch productBarcode {
    case let .UPCA(numberSystem, identifier, check):
        println("UPC-A with value of \(numberSystem), \(identifier), \(check).")
    case let .QRCode(productCode):
        println("QR code with value of \(productCode).")
    }
    // 輸出 "QR code with value of ABCDEFGHIJKLMNOP."

原始值(Raw Values)

相關值小節(jié)的條形碼例子中演示了一個枚舉的成員如何聲明它們存儲不同類型的相關值。作為相關值的替代,枚舉成員可以被默認值(稱為原始值)預先填充,其中這些原始值具有相同的類型。

這里是一個枚舉成員存儲原始 ASCII 值的例子:

    enum ASCIIControlCharacter: Character {
        case Tab = "\t"
        case LineFeed = "\n"
        case CarriageReturn = "\r"
    }

在這里,稱為ASCIIControlCharacter的枚舉的原始值類型被定義為字符型Character,并被設置了一些比較常見的 ASCII 控制字符。字符值的描述請詳見字符串和字符Strings and Characters部分。

注意,原始值和相關值是不相同的。當你開始在你的代碼中定義枚舉的時候原始值是被預先填充的值,像上述三個 ASCII 碼。對于一個特定的枚舉成員,它的原始值始終是相同的。相關值是當你在創(chuàng)建一個基于枚舉成員的新常量或變量時才會被設置,并且每次當你這么做得時候,它的值可以是不同的。

原始值可以是字符串,字符,或者任何整型值或浮點型值。每個原始值在它的枚舉聲明中必須是唯一的。當整型值被用于原始值,如果其他枚舉成員沒有值時,它們會自動遞增。

下面的枚舉是對之前Planet這個枚舉的一個細化,利用原始整型值來表示每個 planet 在太陽系中的順序:

    enum Planet: Int {
        case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
    }

自動遞增意味著Planet.Venus的原始值是2,依次類推。

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

    let earthsOrder = Planet.Earth.rawValue
    // earthsOrder is 3

通過參數(shù)為rawValue構(gòu)造函數(shù)創(chuàng)建特定原始值的枚舉。這個例子通過原始值7識別Uranus

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

然而,并非所有可能的Int值都可以找到一個匹配的行星。正因為如此,構(gòu)造函數(shù)可以返回一個可選的枚舉成員。在上面的例子中,possiblePlanetPlanet?類型,或“可選的Planet”。

如果你試圖尋找一個位置為9的行星,通過參數(shù)為rawValue構(gòu)造函數(shù)返回的可選Planet值將是nil

    let positionToFind = 9
    if let somePlanet = Planet(rawValue: positionToFind) {
        switch somePlanet {
        case .Earth:
            println("Mostly harmless")
        default:
            println("Not a safe place for humans")
        }
    } else {
        println("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)語句獲得一個可選Planet,如果可選Planet可以被獲得,把somePlanet設置成該可選Planet的內(nèi)容。在這個范例中,無法檢索到位置為9的行星,所以else分支被執(zhí)行。