欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Swift中enum枚舉類型的用法

 更新時間:2016年06月28日 18:29:31   作者:火鏡先生  
Swift中通過enum關(guān)鍵字可以直接創(chuàng)建出枚舉對象,而且可以使用switch和case語句來進行流程控制,十分強大和靈活,這里我們就來詳解Swift中enum枚舉類型的用法

一、引言

在Objective-C語言中,沒有實際上是整型數(shù)據(jù),Swift中的枚舉則更加靈活,開發(fā)者可以不為其分配值類型把枚舉作為獨立的類型來使用,也可以為其分配值,可以是字符,字符串,整型或者浮點型數(shù)據(jù)。

二、枚舉語法

Swift中enum關(guān)鍵字來進行枚舉的創(chuàng)建,使用case來創(chuàng)建每一個枚舉值,示例如下:

//創(chuàng)建姓氏枚舉,和Objective-C不同,Swift枚舉不會默認分配值
enum Surname {
  case 張
  case 王
  case 李
  case 趙
}
//創(chuàng)建一個枚舉類型的變量
var myName = Surname.張
//如果可以自動推斷出類型 則枚舉類型可以省略
myName = .李
var myName2:Surname = .王

同樣可以將枚舉值都寫在同一個case中,使用逗號分隔:
enum Planet {
  case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

枚舉經(jīng)常會和Switch語句結(jié)合使用,示例如下:
switch myName {
case .張:
  print("姓氏張")
case .王:
  print("姓氏王")
case .李:
  print("姓氏李")
case .趙:
  print("姓氏趙")
}

三、枚舉的相關(guān)值

Swift中的枚舉有一個很有意思的特點,其可以設(shè)置一些相關(guān)值,通過相關(guān)值,開發(fā)者可以從公用的枚舉值中獲取到傳遞的額外相關(guān)值,示例如下:

enum Number {
  case one(count:Int)
  case two(count:Int)
  case three(count:Int)
  case four(count:Int)
}
var num = Number.one(count: 5)
switch num {
  //獲取num的相關(guān)值
case Number.one(let count):
  print(count)
default:
  print(num)
}
//如果一個枚舉值所有的相關(guān)中都是常量,let關(guān)鍵字也可以提取到括號外面
switch num {
  //獲取num的相關(guān)值
case let Number.one(count):
  print(count)
default:
  print(num)
}

有了相關(guān)值這樣的句法,大大的增加了枚舉的靈活性,例如一個形狀枚舉,可能的枚舉值有矩形,圓形等,矩形的枚舉值就可以提供寬高的相關(guān)值,圓形的枚舉值就可以提供半徑的相關(guān)值,是開發(fā)更加靈活。

四、枚舉的原始值

原始值也可以理解為為枚舉設(shè)置一個具體類型,示例如下:

enum Char:String {
  case a = "A"
  case b = "B"
  case c = "C"
}
//”A“
var char = Char.a.rawValue

注意,如果枚舉是Int類型的,則類似于Objective-C,枚舉的原始值會從第一個開始之后依次遞增:

enum Char:Int{
  case a = 0
  case b
  case c
}
//1
var char = Char.b.rawValue

同樣可以通過原始值的方式來進行枚舉對象的創(chuàng)建,示例如下:

enum Char:Int{
  case a = 0
  case b
  case c
}
//1
var char = Char.b.rawValue
//b
var char2 = Char(rawValue:1)

在通過原始值進行枚舉對象創(chuàng)建的時候,有可能創(chuàng)建失敗,例如傳入的原始值并不存在,這時會返回Optional值nil。

四、遞歸枚舉

遞歸枚舉是Swift枚舉中一個難于理解的地方,實際上也并非十分難于理解,開發(fā)者只要明白枚舉的實質(zhì),遞歸枚舉就很好理解。首先,遞歸是一種算法,可以簡單理解為自己調(diào)用自己,而枚舉實際上并不是函數(shù),它并不執(zhí)行某項運算,它只是表達一個數(shù)據(jù)或者說他也可以表達一種表達式,示例如下:

enum Expression {
  //表示加
  case add
  //表示減
  case mul
}

前面有提到過相關(guān)值的概念,因此,對于上述例子,可以為add和mul枚舉值添加兩個相關(guān)值作為參數(shù)。

enum Expression {
  //表示加
  case add(Int,Int)
  //表示減
  case mul(Int,Int)
}

如此,如下的寫法實際上就可以代表一個5+5的表達式:

var exp = Expression.add(5, 5)

還是需要強調(diào)一點,這個exp只是表達了5+5這樣一個約定的表達式,它并沒有真正進行5+5的運算。現(xiàn)在問題就來了,使用如上的枚舉,怎樣來表達類似(5+5)*5這樣的復合表達式呢?可以使用遞歸枚舉來實現(xiàn),即將(5+5)作為枚舉值得相關(guān)值再次創(chuàng)建枚舉,改造如下:

enum Expression {
  //單值數(shù)據(jù)
  case num(Int)
  //表示加 indirect為遞歸枚舉關(guān)鍵字
  indirect case add(Expression,Expression)
  //表示減
  indirect case mul(Expression,Expression)
}
var exp1 = Expression.num(5)
var exp2 = Expression.num(5)
var exp3 = Expression.add(exp1, exp2)
var exp4 = Expression.mul(exp1, exp3)

上面exp4實際上就表達了(5+5)*5這樣一個過程,注意遞歸的枚舉值必須加上indirect關(guān)鍵字來聲明。處理遞歸枚舉最好的方式是通過遞歸函數(shù),示例如下:

func expFunc(param:Expression) -> Int {
  //進行枚舉判斷
  switch param {
    //如果是單獨數(shù)字 直接返回
  case .num(let p):
    return p
    //如果是加法 則進行遞歸加
  case .add(let one, let two):
    return expFunc(one)+expFunc(two)
    //如果是乘法 則進行遞歸乘
  case .mul(let one, let two):
    return expFunc(one)*expFunc(two)
  }
}
//50
expFunc(exp4)

如果枚舉中所有的case都是可遞歸的,可以將整個枚舉聲明為可遞歸的:

indirect enum Expression {
  //單值數(shù)據(jù)
  case num(Int)
  //表示加 indirect為遞歸枚舉關(guān)鍵字
  case add(Expression,Expression)
  //表示減
  case mul(Expression,Expression)
}

五、一些重點難點總結(jié)
枚舉的語法,enum開頭,每一行成員的定義使用case關(guān)鍵字開頭,一行可以定義多個關(guān)鍵字

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

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

上例中North,South,East,West的值并不等于0,1,2,3,而是他們本身就是自己的值,且該值的類型就是CompassPoint

var directionToHead = CompassPoint.West 
//directionToHead是一個CompassPoint類型,可以被賦值為該類型的其他值
//當設(shè)置directionToHead的值時,他的類型是已知的,因此可以省略East的類型
directionToHead = .East

使用switch分開枚舉的值,以進行的不同的操作。switch內(nèi)的case必須包含枚舉的所有分支,否則編譯出錯。當然,列舉所有枚舉值不太方便時,可以使用default

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"

枚舉的元素可以是結(jié)合值(associated value),下面通過一個可以存儲一維條形碼(由3個整數(shù)組成)和二維條形碼(由字符串組成)的枚舉條形碼實例來說明

enum Barcode {
  case UPCA(Int, Int, Int)
  case QRCode(String)
}
//定義一個變量。該變量即可被賦值為3個整數(shù),又可被賦值為一個字符串,但都是Barcode類型的枚舉值
var productBarcode = Barcode.UPCA(8, 85909_51226, 3)
productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

//使用switch時,case內(nèi)可區(qū)分條形碼種類,可使用變量或常量獲得結(jié)合值
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."

在case內(nèi)部,如果其類型都為let或var,則該關(guān)鍵字可提前到case和枚舉類型中間,如:

case let .UPCA(numberSystem, identifier, check):

原始值類型的枚舉在枚舉名后緊跟數(shù)據(jù)類型,其枚舉的成員在定義時已經(jīng)賦予了初始值,且不能改變,與結(jié)合值類型的枚舉相比,結(jié)合值是在將枚舉值賦予一個變量時,才設(shè)置了那個枚舉的值。

原始值枚舉更像C語言的枚舉,比如整數(shù)型的原始值枚舉,其成員的值如果未指定,則是遞增的。

原始值枚舉也像字典類型,并且是雙向字典,因為他既可以通過枚舉成員獲得該成員原始值,又可以通過原始值,獲得枚舉成員。由此也可以見得,這種枚舉的原始值是不能出現(xiàn)相同值的

//原始值枚舉的類型緊跟枚舉名后,其成員的原始值的數(shù)據(jù)類型都是這個指定的類型
enum ASCIIControlCharacter: Character {
  case Tab = "\t"
  case LineFeed = "\n"
  case CarriageReturn = "\r"
}
//Int類型的原始值枚舉成員的原始值是遞增的,比如Venus的值是2,Earth的值是3
enum Planet: Int {
  case Mercury = 1, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}
//可以通過toRaw方法獲得枚舉成員的原始值
let earthsOrder = Planet.Earth.toRaw()
// earthsOrder 的值是 3,數(shù)據(jù)類型是Int

//可以通過fromRaw方法獲得原始值對應的枚舉成員
let possiblePlanet = Planet.fromRaw(7)
// possiblePlanet 的數(shù)據(jù)類型 Planet? 值是 Planet.Uranus

//因為fromRaw的原始值可能沒有對應的枚舉成員,所以返回的類型是一個可選變量值
let positionToFind = 9
if let somePlanet = Planet.fromRaw(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)")
}
// 枚舉定義中沒有原始值為9的成員,所以打印 "There isn't a planet at position 9"

相關(guān)文章

  • Swift使用編解碼庫Codable的過程詳解

    Swift使用編解碼庫Codable的過程詳解

    Codable 是 Swift 引入的全新的編解碼庫,使開發(fā)者更方便的解析JSON 或 plist 文件,支持枚舉、結(jié)構(gòu)體和類,這篇文章主要介紹了Swift使用編解碼庫Codable,需要的朋友可以參考下
    2023-09-09
  • Swift自定義UITableViewCell背景色

    Swift自定義UITableViewCell背景色

    這篇文章主要為大家詳細介紹了Swift自定義UITableViewCell背景色,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Swift中的指針操作詳解

    Swift中的指針操作詳解

    從傳統(tǒng)的C代碼和與之無縫配合的Objective-C代碼遷移到Swift并非小工程,我們的代碼庫肯定會時不時出現(xiàn)一些和C協(xié)作的地方,如果想要繼續(xù)使用那些C API的話,了解一些基本的Swift指針操作和使用的知識會很有幫助。下面通過這篇文章一起來學習下吧。
    2017-01-01
  • Swift教程之枚舉類型詳解

    Swift教程之枚舉類型詳解

    這篇文章主要介紹了Swift教程之枚舉類型詳解,本文講解了枚舉語法、匹配枚舉值與switch語句、關(guān)聯(lián)值、原始值等內(nèi)容,需要的朋友可以參考下
    2015-01-01
  • Swift編程之枚舉類型詳解

    Swift編程之枚舉類型詳解

    這篇文章主要介紹了Swift編程之枚舉類型,講解了枚舉語法、匹配枚舉值與switch語句、關(guān)聯(lián)值、原始值等內(nèi)容,Swift中枚舉類型是最重要的類型,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 初步理解Swift中的泛型

    初步理解Swift中的泛型

    這篇文章主要介紹了初步理解Swift中的泛型,是Swift入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-07-07
  • EvenLoop模型在iOS的RunLoop應用示例

    EvenLoop模型在iOS的RunLoop應用示例

    這篇文章主要為大家介紹了EvenLoop模型在iOS的RunLoop應用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 淺談Swift編程中switch與fallthrough語句的使用

    淺談Swift編程中switch與fallthrough語句的使用

    這篇文章主要介紹了Swift編程中switch與fallthrough語句的使用,用于基本的流程控制,需要的朋友可以參考下
    2015-11-11
  • 深入講解Swift中的模式匹配

    深入講解Swift中的模式匹配

    在Swift中,一些模式已經(jīng)被語言特性所吸收,你在使用Swift甚至察覺不出這類問題的存在,下面這篇文章主要給大家介紹了關(guān)于Swift中模式匹配的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2018-08-08
  • swift依賴注入和依賴注入容器詳解

    swift依賴注入和依賴注入容器詳解

    這篇文章主要為大家介紹了swift依賴注入和依賴注入容器詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01

最新評論