前言:
本篇僅為視頻學(xué)習(xí)筆記
枚舉的基本用法
我們開看一下抬伺,Swift中的枚舉事秀,一說到枚舉捉撮,在以前學(xué)習(xí)C語言當(dāng)中也知道怕品,但是Swift的枚舉對比C語言中的枚舉,肯定是強(qiáng)大許多的巾遭。
回顧一下之前我們C語言的枚舉肉康,其實(shí)本質(zhì)就是什么,本質(zhì)就是整型灼舍。以前枚舉吼和,就是0、1骑素、2炫乓、3、4這些整型献丑,但是swift中的枚舉就不一樣了末捣。
enum Direction { case north case south case east case west }
根據(jù)上面代碼,我們來看一下创橄,枚舉是怎么定義的箩做?定義非常簡單。直接enum,然后Direction是枚舉的名稱妥畏,內(nèi)部那么多case就代表邦邦,枚舉有多少個(gè)成員安吁。那很明顯Direction這個(gè)枚舉類型,它有4個(gè)成員燃辖。Direction是方向的意思鬼店,它4個(gè)成員是東、南黔龟、西薪韩、北。
上面代碼還可以這樣寫捌锭,它們完全是等價(jià)的如下:
enum Direction { case north, south, east, west }
那么怎么用呢俘陷?很簡單,如下:
var dir = Direction.west dir = Direction.east dir = .north print(dir) // north
如果我們要定義一個(gè)枚舉變量观谦,我們定義一個(gè)dir枚舉變量拉盾,再把Direction.west賦值給它。由于我們Swift編譯器會自動(dòng)推斷dir這個(gè)類型豁状,所以var dir = 不用聲明類型捉偏。很明顯它就是Direction類型的。
然后泻红,一旦賦值完成之后呢夭禽,dir就是Direction這種類型。以后我們可以修改它的值谊路,修改它的值讹躯,也只能給它賦值Direction中四個(gè)成員中的一個(gè)。因?yàn)檫@個(gè)類型缠劝,已經(jīng)固定死了潮梯,就是Direction。
那么賦值的話惨恭,我們可以第一種Direction.east秉馏,賦值另外一個(gè)值。那么脱羡,一當(dāng)你確定了這個(gè)dir是Direction類型萝究,那你可以在賦值過程中可以省略前面的Direction,直接 .north锉罐。其實(shí)就是case north這個(gè)家伙賦值給了dir帆竹。
那么到時(shí)候,我們直接打印枚舉的話氓鄙,它會將dir成員的名字打印出來馆揉。可以自己去嘗試一下抖拦。
switch dir { case .north: print("north") case .south: print("south") case .east: print("east") case .west: print("west") }
然后升酣,他也可以用在switch語句中,如上态罪。switch這個(gè)dir噩茄。我們知道swift語句要保證處理所有情況,很明顯dir是Direction類型的复颈。Direction類型一共有4個(gè)值(成員)绩聘,我們case 4個(gè),其實(shí)就可以了耗啦。
關(guān)聯(lián)值 (Associaated Values)
那么凿菩,我么再來看一下關(guān)聯(lián)值,我們swift枚舉中是可以設(shè)置一個(gè)關(guān)聯(lián)值的帜讲。那是什么意思呢衅谷?
★ 有時(shí)會將枚舉的成員值跟其他類型的關(guān)聯(lián)存儲在一起,會非常有用
例子 - 1
相當(dāng)于就是這樣子似将,如下:
enum Score { case point(Int) case grade(Character) }
比如說获黔,分?jǐn)?shù)Score這個(gè)枚舉,我們知道分?jǐn)?shù)的話在验,很多時(shí)候分?jǐn)?shù)可能分兩種玷氏,一種是有具體的值的 case point(Int),比如說你考了96分腋舌,98分盏触,100分,那這種分?jǐn)?shù)是有具體值的块饺。但有時(shí)候耻陕,地方的考試成績給你的分?jǐn)?shù),case grade(Character)可能給你拿A,還是拿B刨沦,還是拿A+诗宣,A、B想诅、C召庞、D 四個(gè)等級。
所以說分?jǐn)?shù)可能是有數(shù)值的来破,或者是用A篮灼、B、C徘禁、D四個(gè)字符來表達(dá)诅诱。所以說,分?jǐn)?shù)有兩種情況送朱。所以呢娘荡,可以如下面那樣定義:
case point(Int) case grade(Character)
也就是說干旁,如果我們要定義一個(gè)分?jǐn)?shù)變量的話,如下:
var score = Score.point(96) score = .grade("A")
那么,第一種情況炮沐,我們可以Score.point(96)争群,point就是具體的分?jǐn)?shù),我可以傳一個(gè)96進(jìn)去大年,那么這個(gè)96其實(shí)就相當(dāng)于 point(Int)中的Int换薄。那么就這樣的話,就將這個(gè)96跟我們的score這個(gè)枚舉變量關(guān)聯(lián)起來了翔试。然后呢轻要,
然后呢,由于我們這個(gè)分?jǐn)?shù)呢垦缅,也可以是case grade(Character)這種類型冲泥,所以呢,我可以給它賦值另外一個(gè)** .grade("A")**失都,但是它接收的是一個(gè)字符(Character),比如說柏蘑,比考的這個(gè)分?jǐn)?shù)的等級,你這個(gè)成績是A,那么我們可以傳進(jìn)去一個(gè)A給你粹庞。
你看咳焚,這就很好表達(dá)了,成績有兩種庞溜,一種是用數(shù)值來表達(dá)革半,一種是用字符來表達(dá)。
而且流码,再思考一個(gè)問題又官,枚舉一般用在什么地方。是不是你這個(gè)變量的取值漫试,就那固定的幾種六敬,就應(yīng)該用枚舉。
比如說驾荣,一年有多少個(gè)季節(jié)外构,這個(gè)季節(jié)season,這種東西肯定用枚舉比較好播掷,因?yàn)橹挥写合那锒蟊啵@4個(gè)季節(jié)。所以歧匈,季節(jié)一般我們用枚舉垒酬,是最好的。那分?jǐn)?shù)也不是一樣嗎?我們現(xiàn)在分?jǐn)?shù)就兩種勘究,要么就是有數(shù)值的矮湘,要么是有字符的,說一分?jǐn)?shù)就兩種選擇乱顾,所以把它定義為枚舉板祝,還是比較合適的宫静。
switch score { case let .point(i): print(i,"point") case let .grade(i): print("grade",i) } // grade A
那么再來舉一個(gè)例子走净,我們先看一下這個(gè)switch用在score上面是怎么用的,很簡單孤里。一共有兩種情況,要么是.point伏伯,要么是.grade。這兩種嘛捌袜,而且呢说搅,由于Int和Character,是到時(shí)候可以關(guān)聯(lián)一個(gè)值虏等,接收一個(gè)值的弄唧。
所以呢,建議大家再做case的時(shí)候 case let .point(i): ,point里面是要寫一個(gè)值的霍衫,比如說這個(gè)i候引。
那么這個(gè)i你要它變成常量呢?還是變量呢敦跌?你就可以再左邊寫一個(gè)let或者var澄干,這個(gè)取決于你自己。
那我們這個(gè)score最后柠傍,給它賦值的是score = .grade("A")麸俘,很明顯這個(gè)score是符合這個(gè) case let .grade(i): 的。到時(shí)候這個(gè)A會賦值給這個(gè) i,所以惧笛,最后這個(gè)print(i,"grade")打印出來从媚,肯定是grade和這個(gè)A。合起來就是 // grade A
整體代碼
例子 - 2
enum Date { case digit(year: Int, month: Int, day: Int) case string(String) } var date = Date.digit(year: 2011, month: 9, day: 10) date = .string("2011-09-10") switch date { case .digit(let year,let month,let day): print(year, month, day) case let .string(value): print(value) }
這是一個(gè)日期Date患整,日期也是一樣的拜效,我們可以有兩種表達(dá)形式,第一種表達(dá)形式case digit(year: Int, month: Int, day: Int)是用數(shù)字的形式并级,比如所你傳年拂檩、月、日嘲碧,代表日期稻励。第二種表達(dá)形式case string(String),你可以直接傳一個(gè)字符串給我。
我們再來看一下望抽,現(xiàn)在的這個(gè)日期Date枚舉加矛?日期Date的第一個(gè)枚舉成員,注意看煤篙,跟例1中的Score枚舉中的第一個(gè)枚舉成員斟览,有什么區(qū)別。之前Score辑奈,它的第一個(gè)枚舉成員關(guān)聯(lián)的類型苛茂,是沒有寫名稱的,但是在Date第一個(gè)枚舉成員中鸠窗,我們關(guān)聯(lián)的類型是寫名稱的妓羊,其實(shí),如果你樂意的話稍计,完全可以寫幾個(gè)名稱躁绸,來表達(dá)一下,這三個(gè)值代表什么臣嚣。所以净刮,你看我寫了一個(gè)year、 month硅则、day淹父。其實(shí)這三個(gè)名稱,這三個(gè)標(biāo)簽抢埋,你是可以省略的弹灭,但有時(shí)候,你想讓別人明確的知道你想要什么揪垄,所以可以寫一個(gè)標(biāo)簽名穷吮。
那么,我們來看一下饥努,那么怎么定義一個(gè)這樣的變量捡鱼?其實(shí),很簡單酷愧,如下:
var date = Date.digit(year: 2011, month: 9, day: 10) date = .string("2011-09-10")
日期有兩種表達(dá)形式驾诈,所以什么情況下用枚舉呢?如果你這個(gè)類型溶浴,只有幾個(gè)固定的取值的乍迄,那么就可以用枚舉
那么,這個(gè)switch date 也是一樣的士败,那么這個(gè)switch再擴(kuò)展一個(gè)闯两,由于digit褥伴,它接收了三個(gè)家伙,所以肯定有year漾狼、month重慢、day的,跟前面講的那個(gè)有什么不一樣逊躁。
前邊講的這個(gè)let修飾詞似踱,就是常量修飾詞,我是寫在這個(gè)整體的前面稽煤。那么核芽,digit你會發(fā)現(xiàn)三個(gè)year、month念脯、day是單獨(dú)寫的狞洋。
那是弯淘,什么意思呢绿店?也就是.digit(let year,var month,let day)中year、month庐橙、day哪個(gè)是常量假勿,哪個(gè)是變量,都收完全可以自己定的态鳖。
但是如果你這三個(gè)家伙转培,什么都不寫,統(tǒng)一把這個(gè)let寫到了整體的前面浆竭,代表year浸须、month、day都是let 邦泄。如果你在前面統(tǒng)一寫了一個(gè)var,那么year删窒、month、day代表的就是變量顺囊,那么我們case一下肌索,就可以把它們當(dāng)作變量來使用。
case let .string(value):
這個(gè)let寫在前面特碳,就代表value它是常量诚亚,當(dāng)然這個(gè)let 你可以放到value 前面,也是可以的午乓。
var score = Score.point(96) score = .grade("A")
這就是關(guān)聯(lián)值站宗,但時(shí)候我這個(gè)枚舉變量,可以把其它類型的值益愈,關(guān)聯(lián)存儲在一起梢灭,也就是說這個(gè)score變量它的內(nèi)存中其實(shí)是有96這個(gè)值的,那么第二個(gè)score如果存儲這個(gè)A的話,也就意味這這個(gè)score它內(nèi)存中是有這個(gè)A字符的內(nèi)容的或辖。
var date = Date.digit(year: 2011, month: 9, day: 10) date = .string("2011-09-10")
還有這個(gè)date變量瘾英,到時(shí)候它的內(nèi)存中是有2011、9颂暇、10這三個(gè)整型值缺谴,也就是說這三個(gè)整型值,其實(shí)是存儲在date這個(gè)枚舉變量的內(nèi)存里面耳鸯。那么下面這個(gè)字符串也是一樣的湿蛔。
關(guān)聯(lián)值,你可以認(rèn)為將各種類型的數(shù)據(jù)直接存儲在枚舉變量里面县爬,這個(gè)呢阳啥,我們稱之為關(guān)聯(lián)值。
★ 必要時(shí)财喳,let也可以改成var
關(guān)聯(lián)值舉例
比如說察迟,我們講的密碼,我們手機(jī)的密碼一般有兩種耳高,一種是輸入密碼扎瓶,一種是輸入數(shù)字。
數(shù)字這個(gè)舉例是4個(gè)泌枪,輸入4個(gè)數(shù)字作為你手機(jī)的解鎖密碼概荷,當(dāng)然你也可以用手勢密碼。那么碌燕,密碼輸入误证,既然就兩種,我們是完全可以想象成枚舉的修壕,因?yàn)槟憔蛢煞N取值愈捅。
enum Password { case number(Int,Int,Int) case gesture(String) }
所以,我們注意看,你這密碼有兩種叠殷,第一種是數(shù)字密碼改鲫,數(shù)字密碼我只要求你輸入4個(gè),所以是不是林束,我們就關(guān)聯(lián)4個(gè)整型數(shù)據(jù)像棘。還有一種是手勢密碼,所以叫g(shù)esture壶冒。那么手勢密碼我們就用字符串來表達(dá)缕题。
那么怎么用字符串來表達(dá)呢?比如說胖腾,像這個(gè)密碼盤我們就可以怎么做呢烟零,我們就可以從左到右瘪松,從上到下,給它們編一個(gè)序號锨阿,比如說:1宵睦、2、3墅诡、4壳嚎、5、6末早、7烟馅、8、9然磷。其實(shí)如圖所示郑趁,這個(gè)手勢密碼呢就是12369。那么為什么用字符串呢姿搜?我們思考一下寡润,這個(gè)手勢密碼是不是可能很復(fù)雜。經(jīng)過的路徑比較多痪欲。如果你用整型表達(dá)悦穿,可能很不完整。那么业踢,我們干脆,用字符串礁扮,這樣更好知举。
var pwd = Password.number(3, 5, 7,8) pwd = .gesture("12369")
假如我們的密碼是3,5太伊,7雇锡,8,手勢密碼按照剛才的12369僚焦,我們就可以這樣表達(dá)锰提。
enum Password { case number(Int,Int,Int,Int) case gesture(String) } var pwd = Password.number(3, 5, 7,8) pwd = .gesture("12369") switch pwd { case let .number(n1, n2, n3, n4) print("number is",n1,n2,n3,n4) case let .gesture(str) print("gesture is",str) }