枚舉
什么是枚舉?
還是說回到數(shù)據(jù)類型。我們在表達(dá)某個事物的時候,可以用數(shù)字,文字進(jìn)行描述;可以用流程語句來描述一段邏輯;還可以用函數(shù),來打包某件事,用于更加方便的調(diào)用。
某些事物的性質(zhì),可以用有限的列舉來表達(dá),比如
家具的材質(zhì):木,金屬,石材
汽車的品牌:比亞迪,特斯拉
為了更方便的描述事物,我們引入了枚舉的概念。
枚舉的形式
在下面這些例子中,我們使用了枚舉:
// 列出我們經(jīng)常吃的一些水果。
enum Fruit {
case apple
case banana
case orange
}
// 列出星期一到星期天
enum WeekDay {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
case Saturday
case Sunday
}
enum是關(guān)鍵詞,代表要創(chuàng)建一個枚舉;Fruit是枚舉的名稱,首字母大寫;大括號括起枚舉定義;case關(guān)鍵詞定義的是枚舉成員值。
這里有個概念,叫做一等類型,比如
Int,String等基本類型,他們可以作為參數(shù),可以作為返回值。我們學(xué)過的函數(shù)也是一等類型,枚舉enum也是一等類型。
枚舉的訪問
- 訪問枚舉中的某個成員值
使用枚舉名.成員值的形式,可以訪問到枚舉中的具體成員值。
enum Fruit {
case apple
case banana
case orange
}
var a = Fruit.apple
a // apple
我們打印a的數(shù)據(jù)類型看看。
print(type(of: a))
// Fruit
a的數(shù)據(jù)類型是Fruit,有點像函數(shù),是一個自定義的數(shù)據(jù)類型。
我們還可以給a賦值為其他的成員值。
var a = Fruit.orange
a // orange
a的值就變成了orange。
Swift語言提供了簡寫的方式賦值。
a = .banana
print(a) // banana
- 遍歷枚舉的成員值
既然枚舉是一串?dāng)?shù)據(jù),我們應(yīng)該就可以使用for-in語句進(jìn)行遍歷訪問,但是直接用for i in Fruit這種語句是無法進(jìn)行遍歷訪問的,因為Fruit并不是一個集合值。
我們需要加一些裝飾語句。首先,定義枚舉的時候,要聲明遵循CaseIterable協(xié)議(協(xié)議的概念我們后面再說),然后在遍歷的時候,要使用.allCases表示枚舉成員的集合。表達(dá)如下:
enum Fruit: CaseIterable {
case apple
case banana
case orange
}
for i in Fruit.allCases {
print(i)
}
// apple banana orange
枚舉的應(yīng)用
- 結(jié)合switch
配合switch語句,我們可以根據(jù)枚舉的不同成員值,匹配出不同的動作。
var a = Fruit.apple
switch a {
case .apple:
print("我喜歡吃蘋果。")
case .banana:
print("我喜歡吃香蕉。")
case .orange:
print("我喜歡吃橘子。")
}
// 我喜歡吃蘋果。
這里需要注意的是,switch需要將枚舉中的成員值列舉完全,如果不需要列舉完全,可以搭配使用default。
var a = Fruit.orange
switch a {
case .apple:
print("我喜歡吃蘋果。")
case .banana:
print("我喜歡吃香蕉。")
default:
print("我喜歡吃其他水果。")
}
// 我喜歡吃其他水果。
- 關(guān)聯(lián)值
枚舉看起來有很多成員值,但是同一時間,枚舉只能呈現(xiàn)一個值。
如上面的例子中,如果a的值是蘋果,switch判斷出來的執(zhí)行語句就是“我喜歡吃蘋果?!?/code>
利用這個特性,我們可以給枚舉先定義一個框架,然后再賦值。
舉例,我想選一種方式,與客戶王總溝通業(yè)務(wù),有電話溝通和郵件溝通兩種方式:
enum Communication {
case phone(Int)
case email(String)
}
我先定義了一個枚舉框架,這個框架中沒有給任何的賦值,當(dāng)我決定時,我再進(jìn)行賦值:
var wangzong = Communication.phone(13888888888)
// 或者是
var wangzong = Communication.email(wangzong@163.com)
那么,如何取出這個值呢,還是用switch:
switch wangzong {
case .phone(let phoneNumner):
print("打電話(\(phoneNumner))給王總。")
case .email(let emailAddress):
print("發(fā)郵件(\(emailAddress))給王總。")
}
這是我理解的關(guān)聯(lián)值的概念。
拓展的概念和應(yīng)用
- 原始值
我們看下面這個枚舉:
enum tranlate: String {
case apple = "蘋果"
case banana = "香蕉"
case orange = "橘子"
}
=后面連接的字符"蘋果"就是成員值的原始值。要注意的是,前面需要指定數(shù)據(jù)類型,后面的原始值也要遵守這個指定的數(shù)據(jù)類型。
如何訪問這個原始值呢?
let word = tranlate.apple.rawValue
// 蘋果
這里,我們使用了.rawValue訪問到了原始值。
原始值,其實有默認(rèn)值。我們繼續(xù)看下面的例子:
enum tranlate: Int {
case apple
case banana
case orange
}
let word = tranlate.orange.rawValue
// 2
如果指定原始值為Int,但是后面卻沒有指定,默認(rèn)就是從0開始,所以orange的原始值是2。
如果指定原始值為String呢?
enum tranlate: String {
case apple
case banana
case orange
}
let word = tranlate.orange.rawValue
// orange
這是,默認(rèn)是原始值就是成員值本身。
- 遞歸
枚舉的遞歸需要用到函數(shù)的概念。
待補(bǔ)充………………