Swift學習筆記(六)枚舉類型

枚舉類型

枚舉語法

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

注意:與C或者Objective-C不同的是,在Swift語言中枚舉類型的成員初始的時候不會被默認賦值成整數值,在CompassPoint這個例子中,North, South, East, West默認不會隱式的等於0,1,2,3。取而代之的是不同的枚舉成員將要用什麼類型以及賦值什麼值都是可以自己控制的,可以在定義CompassPoint這個枚舉的時候指定.


多個成員還可以用一行來定義,他們之間用逗號分割

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

每個枚舉的定義都是定義了一個全新的類型,就像Swfit中的其他的類型一樣,枚舉的名稱(CompassPoint, Plant)應該是以一個大寫字母開頭,讓他們是單數類型而不是複數類型,從而讓他們可以不言而喻。

var directionToHead = CompassPoint.West

directionToHead在初始化過程中被賦值成CompassPoint中的某一個可能的值的時候,它的類型就可以被推測出來來了。一旦directionToHead被聲明成是CompassPoint類型,那麼你就可以簡短的使用逗號表達式來給它賦值成其他的CompassPoint當中的值了:

directionToHead = .East

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


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

關聯值

Swift中當你定義一個枚舉成員的時候,你可以給他關聯任何的類型,而且如果需要的話每個成員可以有不同的關聯類型。枚舉類型的這個特性和其他語言當中的辨別聯合,標記聯合或者變體很像。

一個可以定義兩個格式的產品條形碼的枚舉看起來是這樣的:

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

可以這麼理解

定義了一個叫做Barcode的枚舉類型,它可以有一個UPCA成員,這個成員關聯了一個包含4個整型數值的元組,同時這個枚舉類型還有一個QRCode成員,關聯了一個字符串

這個定義不會生成任何的整型或者字符串值,他只是定義了當一個不可變變量或者變量等於Barcode.UPCA或者Barcode.QRCode的時候它被關聯的值的類型

var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOPQRST")


這兩個不同的類型可以用Switch語句來做檢查。同時,在switch語句中他們相關聯的值也可以被獲取到。你可以把關聯的值當做不可變變量(let來開頭),或者可變變量(var開頭)以在switch的控制體當中使用。

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

如果一個枚舉成員關聯的所有值都被當做不可變變量或者可變變量來使用,那麼你可以在成員名稱之前只放一個let或者var來達到目的

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

原始值(Raw Values)

不同於關聯值,枚舉類型的成員還可以預設置默認值(我們叫他原始值),這些值的類型是相同的。

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

注意:原始值與關聯值不同。原始值應該是在你定義枚舉的代碼中被設置爲預填充值的,就像上述三個ASCII碼。對於一個特定的枚舉成員的原始值始終是相同的。關聯值是當你創建一個基於枚舉的成員的新的常量或變量的時候設置的,並且每次都可以是不同的。

原始值可以是字符串,字符或者其他任何的整型或者浮點型等數字類型。每個原始值在他屬的枚舉類型定義的時候都應該是不同的。如果原始值是整數類型,那麼當其他枚舉成員沒有設置原始值的時候,他們的原始值是這個整型原始值自增長設置的。

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


獲取原始值

let earthOrder = Planet.Earth.rawValue
earthsOrder is 3


rawValue初始化

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


不是所有可能int值都能找到一個匹配的Planet,所以,原始值初始化常常返回一個可選的枚舉成員,上面的possiblePlanet的類型是Planet?

如果你試圖去找到一個在位置9Planet,這個可選的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)")
}
// prints "There isn't a planet at position 9"

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章