Swift之列舉

weixin_34037977發表於2018-01-12

看到網上關於swift基礎知識的文章已經不少了,自己寫這些就當是加深記憶,做自己的小筆記吧。
今天寫關於swift列舉的內容。
1:列舉的語法

// 列舉值也稱為列舉成員值
enum 列舉名稱 {
    case 列舉值1
    case 列舉值2
    case 列舉值3
}

enum YourEnumerationName {
    case EnumerationValue1
    case EnumerationValue2
    case EnumerationValue3
}

當多個成員值出現在同一行時也可以按照下面的寫法來書寫:

enum 列舉名稱 {
    case 列舉值1,列舉值2,列舉值3
}

enum YourEnumerationName {
    case EnumerationValue1, EnumerationValue2,EnumerationValue3
}

2:列舉和switch語句的配合使用

//定義一個列舉型別變數
enum DayEnumeration {
    case yesterday
    case today
    case tomorrow
}

// 宣告一個變數用來表示這個時間列舉
var day = DayEnumeration.today
// 更改day的值
day = .tomorrow

// 使用switch語句
switch day = {
    case .yesterday: 
          print("昨天下雨了")
    case .today: 
          print("今天還在下雨")
    case .tomorrow: 
          print("希望明天不要下雨了")
}
// 列印結果為:希望明天不要下雨了
// 注意在switch語句中需要將所有情況窮舉,如果有不確定的情況或者不需要匹配具體的列舉成員值時,就用default來表示。

3:列舉關聯值
例如我們在使用微信時,如果用手機登陸,可以採用微訊號/手機號/QQ號+密碼的形式,使用電腦版本的時候則需要掃描二維碼,這個時候我們可以將不同的登陸方式用一個列舉來表示,而這時就可以用到列舉的關聯值。
我們可以將這種型別的列舉表示為

enum LoginType {
    case phone(String, String) // 手機登陸
    case computer(String) // 電腦二維碼登陸,二維碼可視作一字串
}

上面這段程式碼可以理解為:定義了一個名為LoginType的列舉型別,他有兩個成員值分別是phone和computer。成員值phone是一個具有(String, String)型別的關聯值,而成員值computer是一個具有String型別的關聯值。

// 使用任意一種方式登陸,如手機登陸
var login = LoginType. phone("zhanghao123","mima456")

上面的例子建立了一個名為login的變數,並將LoginType. phone賦值給他,關聯的元組值為("zhanghao123","mima456")。

// 如果採用電腦二維碼登陸的話,則:
login = .computer("erweimaxinxi")

這時原來我們建立的login變數的值被LoginType.computer及其字串關聯值所替代。
LoginType型別的常量、變數可以儲存一個.phone或者一個.computer及其關聯值。但是同一時間只能儲存.phone和.computer其中的一個。
如果這個時候我們用switch來表示不同的登陸方式,則有:

switch login {
   case .phone(let userName, let password):
        print("loginType is phone")
   case .computer(let userQRCode):
        print("loginType is computer")
}

上面的程式碼可以進一步改寫為:

switch login {
   case  let .phone(userName, password):
        print("loginType is phone")
   case  let .computer(userQRCode):
        print("loginType is computer")
}

4:列舉原始值

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

上面定義了一個使用ASCII 碼作為原始值的列舉。
原始值可以是字串,字元,或者任意整型值或浮點型值。每個原始值在列舉宣告中必須是唯一的。

需要注意的是:原始值和關聯值是不同的。原始值是在定義列舉時被預先填充的值,像上述三個 ASCII 碼。對於一個特定的列舉成員,它的原始值始終不變。關聯值是建立一個基於列舉成員的常量或變數時才設定的值,列舉成員的關聯值可以變化。

原始值的隱式賦值:
在使用原始值為整數或者字串型別的列舉時,不需要顯式地為每一個列舉成員設定原始值,Swift 將會自動為你賦值。
例如,當使用整數作為原始值時,隱式賦值的值依次遞增1。如果第一個列舉成員沒有設定原始值,其原始值將為0。

enum Week: Int {
     case monday = 1
     case tuesday
     case wednesday
     case thursday
     case friday
     case saturday
     case sunday
}

在上面的例子中,Week.monday的顯式原始值為1,Week. tuesday的隱式原始值為2,依次類推。

當使用字串作為列舉型別的原始值時,每個列舉成員的隱式原始值為該列舉成員的名稱。
使用列舉成員的rawValue屬性可以訪問該列舉成員的原始值:

let order = Week.wednesday.rawValue
// order = 3

使用原始值初始化列舉例項:
如果在定義列舉型別的時候使用了原始值,那麼將會自動獲得一個初始化方法,這個方法接收一個叫做rawValue的引數,引數型別即為原始值型別,返回值則是列舉成員或nil。我們可以使用這個初始化方法來建立一個新的列舉例項。但是原始值構造器是一個可失敗構造器,因為並不是每一個原始值都有與之對應的列舉成員。

5:遞迴列舉
遞迴列舉是一種列舉型別,它有一個或多個列舉成員使用該列舉型別的例項作為關聯值。使用遞迴列舉時,編譯器會插入一個間接層。你可以在列舉成員前加上indirect來表示該成員可遞迴。
例如,下面的例子中,列舉型別儲存了簡單的算術表示式:

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

我們也可以將indirect關鍵字寫在enum的前面來表示遞迴:

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

上面定義的列舉型別可以儲存三種算術表示式:純數字、兩個表示式相加、兩個表示式相乘。列舉成員addition和multiplication的關聯值也是算術表示式——這些關聯值使得巢狀表示式成為可能。例如,表示式(a + b) * c,乘號右邊是一個數字,左邊則是另一個表示式。因為資料是巢狀的,因而用來儲存資料的列舉型別也需要支援這種巢狀——這意味著列舉型別需要支援遞迴。下面的程式碼展示了使用ArithmeticExpression這個遞迴列舉建立表示式(a + b) * c

let a = ArithmeticExpression.number(1)
let b = ArithmeticExpression.number(2)
let c = ArithmeticExpression.addition(five, four)
let endValue = ArithmeticExpression.multiplication(c, ArithmeticExpression.number(3))

通過遞迴函式可以直接的操作具有遞迴性質的資料結構:

// 定義一個evaluate函式用來計算ArithmeticExpression表示式的值
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)
    }
}

以上就是關於swift列舉的相關內容。謝謝!

相關文章