Swift 枚舉

Swift 中枚舉的特點(diǎn):

  • 不必給每一個(gè)枚舉成員提供一個(gè)值。(枚舉的 case 默認(rèn)就是一個(gè)值)
  • 枚舉的值可以是 字符串 字符 整形值 浮點(diǎn)值
  • 枚舉成員可以指定任意類型的關(guān)聯(lián)值存儲(chǔ)到枚舉的成員中。
  • 枚舉中可以有函數(shù)
    • 計(jì)算屬性: 提供枚舉的附加信息。
    • 實(shí)例方法: 給 枚舉值(case) 提供相應(yīng)的功能
    • 構(gòu)造方法: 給枚舉提供初始值
    • 可以遵守協(xié)議:提供標(biāo)準(zhǔn)功能。

枚舉的語(yǔ)法

使用 enum 關(guān)鍵字來(lái)定義一個(gè)枚舉:

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

example 1

// CompassPoint 是枚舉的類型
enum CompassPoint {
    //  使用 case 來(lái)定義一個(gè)枚舉實(shí)例
    case North
    case South
    case East
    case West
}

注意點(diǎn):
Swift 的枚舉不會(huì)被賦值一個(gè)默認(rèn)的整形值。例如 objc  中的 0,1,2,3 等。
在example1 中 枚舉變量的值就是:North,South,East 和 West

多個(gè)成員值可以出現(xiàn)在同一行上,用逗號(hào)隔開:
enum Planet {
    case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

每一個(gè)枚舉定義了一個(gè)全新的類型。(和類,結(jié)構(gòu)體一樣)
枚舉變量使用單數(shù)名稱。

獲取枚舉的實(shí)例

var directionToHead = CompassPoint.West

// 修改枚舉實(shí)例(由于類型為 CompassPoint ,類型推斷可以推斷出來(lái),所有可以直接使用 點(diǎn)語(yǔ)法。 )
directionToHead = .East

** 枚舉和 Switch 配合使用 **

  • Switch 語(yǔ)句必須 窮舉所有 的情況。當(dāng)不窮舉的時(shí)候回導(dǎo)致編制出錯(cuò)。
  • 可以使用 default 語(yǔ)句來(lái)處理 case 沒有白涵蓋的枚舉變量。

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

(我的簡(jiǎn)單理解,關(guān)聯(lián)值就是枚舉的 case 變?yōu)樵鏀?shù)據(jù))

// Barcode 枚舉類型
enum Barcode {

    // 具有 (Int, Int, Int, Int) 類型的關(guān)聯(lián)值(元祖)UPCA 為元祖的名稱
    case UPCA(Int, Int, Int, Int)

    // 具有  (String) 類型的關(guān)聯(lián)值(元祖)QRCode 為元祖的名稱
    case QRCode(String)
}

// 關(guān)聯(lián)值的使用 
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3)

// 修改變量的值
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")


// 簡(jiǎn)單條線碼掃描的實(shí)現(xiàn)(太雞巴酷了)
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."




// 簡(jiǎn)潔用法
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."

原始值 和 值操作

枚舉成員可以被默認(rèn)值(稱為原始值)預(yù)填充,這些原始值的類型必須相同。
有點(diǎn)回到 objc 時(shí)代,但是又有很大的不同。
枚舉的值可以是 字符串 字符 整形值 浮點(diǎn)值

// 原始值的類型為 Character 
enum ASCIIControlCharacter: Character {
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageReturn = "\r"
}

原始值和關(guān)聯(lián)值的不同:

  • 原始值必須預(yù)先填充(填充的值類型必須一致)
  • 關(guān)聯(lián)值是后期填充的 (值的類型可以不一致)

隱式賦值

enum Planet: Int {
    // 后面的值會(huì)一次填充
    case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

使用字符串作為枚舉類型的原始值時(shí),每個(gè)枚舉成員的隱式原始值為該枚舉成員的名稱

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

// 用起來(lái)好雞巴爽
let sunsetDirection = CompassPoint.West.rawValue
// sunsetDirection 值為 "West"

枚舉成員的rawValue屬性可以訪問(wèn)該枚舉成員的原始值:

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

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

使用原始值初始化枚舉實(shí)例

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 類型為 Planet? 值為 Planet.Uranus

遞歸枚舉

丫的,沒看懂。我靠。
遞歸枚舉(recursive enumeration)是一種枚舉類型。
它有一個(gè)或多個(gè)枚舉成員使用該枚舉類型的實(shí)例作為關(guān)聯(lián)值。使用遞歸枚舉時(shí),編譯器會(huì)插入一個(gè)間接層。你可以在枚舉成員前加上indirect來(lái)表示該成員可遞歸。

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

// 在枚舉類型開頭加上indirect關(guān)鍵字來(lái)表明它的所有成員都是可遞歸的
indirect enum ArithmeticExpression {
    case Number(Int)
    case Addition(ArithmeticExpression, ArithmeticExpression)
    case Multiplication(ArithmeticExpression, ArithmeticExpression)
}

上面定義的枚舉類型可以存儲(chǔ)三種算術(shù)表達(dá)式:純數(shù)字、兩個(gè)表達(dá)式相加、兩個(gè)表達(dá)式相乘。

單純的遞歸枚舉是沒有什么意義的。
遞歸枚舉結(jié)合遞歸函數(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))



// 這個(gè)才是功能的具體實(shí)現(xiàn)
func evaluate(expression: ArithmeticExpression) -> Int {
    switch expression {
    case .Number(let value):
        return value
    case .Addition(let left, let right):

        // 繼續(xù)函數(shù)的調(diào)用
        return evaluate(left) + evaluate(right)
    case .Multiplication(let left, let right):

        // 繼續(xù)函數(shù)的調(diào)用
        return evaluate(left) * evaluate(right)
    }
}

print(evaluate(product))
// 輸出 "18"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 枚舉為一組相關(guān)的值定義了一個(gè)共同的類型,使得可以在代碼中以類型安全的方式來(lái)使用這些值。 如果熟悉 C 語(yǔ)言,會(huì)知道...
    窮人家的孩紙閱讀 901評(píng)論 1 4
  • 枚舉定義一組相關(guān)值的公共類型,并允許您在代碼中以類型安全的方式使用這些值。 如果你熟悉C,你會(huì)知道C枚舉分配相關(guān)的...
    Joker_King閱讀 297評(píng)論 0 0
  • Swift中不僅提供了 面向過(guò)程的編程支持,也提供了全面的面向?qū)ο蟮闹С?,與普通的面向?qū)ο蟮木幊陶Z(yǔ)言(只支持類)不...
    隨夢(mèng)而飛飛閱讀 5,272評(píng)論 3 4
  • 本章將會(huì)介紹 閉包表達(dá)式尾隨閉包值捕獲閉包是引用類型逃逸閉包自動(dòng)閉包枚舉語(yǔ)法使用Switch語(yǔ)句匹配枚舉值關(guān)聯(lián)值原...
    寒橋閱讀 1,628評(píng)論 0 3
  • enum CompassPoint { case North case South case East case ...
    FengxinLi閱讀 353評(píng)論 0 0

友情鏈接更多精彩內(nèi)容