泛型介紹
你想要給寵物和它們的飼養(yǎng)員做一個(gè)模型。你可以使用不同的值來實(shí)現(xiàn)這一點(diǎn),也可以使用不同的類型來實(shí)現(xiàn)這一點(diǎn)。你將看到逐沙,通過使用類型(而不是值),Swift類型檢查器可以在編譯時(shí)推斷你的代碼洼畅。你不僅在運(yùn)行時(shí)做得更少吩案,從而生成更快的代碼,而且還可以捕獲僅使用值不可能解決的問題帝簇。
由其他值定義的值
假設(shè)你經(jīng)營(yíng)著一家只賣狗和貓的寵物店徘郭,你想用swift的playground來做這個(gè)生意的模型。首先丧肴,你定義了一種類型残揉,PetKind,它可以包含兩種可能的值芋浮,對(duì)應(yīng)于你出售的兩種寵物:
enum PetKind {
case cat
case dog
}
現(xiàn)在抱环,假設(shè)你不僅想構(gòu)建動(dòng)物模型,還想構(gòu)建照顧寵物的員工模型途样。你的員工是高度專業(yè)化的江醇。有些飼養(yǎng)員只照看貓濒憋,有些只照看狗何暇。
所以你定義一個(gè)KeeperKind類型,如下:
struct KeeperKind {
var keeperOf: PetKind
}
然后你可以用以下方法初始化一個(gè)貓管理員和狗管理員:
let catKeeper = KeeperKind(keeperOf: .cat)
let dogKeeper = KeeperKind(keeperOf: .dog)
如何為你的商店建模凛驮,有兩點(diǎn)需要注意裆站。
首先,你通過改變類型的值來代表不同種類的寵物和飼養(yǎng)者黔夭。寵物的種類只有一種—— PetKind——還有一種是飼養(yǎng)者—— KeeperKind宏胯。不同種類的寵物只能用不同的PetKind的值來表示,正如不同種類的飼養(yǎng)者用不同的KeeperKind的值來表示一樣本姥。
第二肩袍,一個(gè)范圍的值可能決定了另一個(gè)值的范圍。具體地說婚惫,KeeperKind值的范圍直接反映了PetKind值的范圍氛赐。
如果你的商店開始出售鳥類魂爪,你只需在PetKind枚舉中添加.bird成員,你就可以立即初始化一個(gè)值艰管,該值描述一個(gè)鳥類飼養(yǎng)員KeeperKind(keeperOf: .bird)滓侍。如果你開始銷售100種不同的寵物,你馬上就能表示100種不同的飼養(yǎng)員牲芋。
相反撩笆,你可以定義第二個(gè)不相關(guān)的枚舉,而不是KeeperKind缸浦。
在這種情況下夕冲,沒有任何東西會(huì)強(qiáng)制執(zhí)行這種關(guān)系,除非你一直在更新一個(gè)類型以鏡像另一個(gè)類型裂逐。如果你PetKind添加啦PetKind.snake耘擂,卻忘了添加EnumKeeperKind.snakeKeeper,那么事情就會(huì)變得紊亂絮姆。
但是使用KeeperKind醉冤,你可以通過PetKind類型的屬性顯式地建立關(guān)系。每一個(gè)可能的PetKind值都意味著一個(gè)相應(yīng)的KeeperKind值篙悯∫涎簦或者你可以說,PetKind集合定義了KeeperKind值集合鸽照。
總而言之螺捐,你可以這樣描述這種關(guān)系:
由其他類型定義的類型
上面的模型基本上是通過改變類型的值來實(shí)現(xiàn)的。現(xiàn)在考慮另一種建模矮燎,通過改變類型本身來實(shí)現(xiàn)定血。
假設(shè)您沒有定義代表各種寵物的單一類型PetKind,而是為你出售的每種寵物定義了不同的類型诞外。如果你采用面向?qū)ο蟮姆绞綄?shí)現(xiàn)澜沟,那么這是一個(gè)相當(dāng)合理的選擇,你可以為每個(gè)寵物使用不同的方法對(duì)它們的行為進(jìn)行建模峡谊。然后你會(huì)得到以下信息:
class Cat {}
class Dog {}
那么如何表示相應(yīng)種類的飼養(yǎng)員呢?你可以簡(jiǎn)單地寫下以下內(nèi)容:
class KeeperForCats {}
class KeeperForDogs {}
但那不是很好茫虽。這種方法的問題與手動(dòng)定義KeeperKind值的并行枚舉完全相同——它依賴于你為每種類型的寵物強(qiáng)制與一種飼養(yǎng)員類型保持關(guān)系。
你真正喜歡的是一種聲明一段關(guān)系的方式既们,就像你為值所建立的關(guān)系一樣濒析。你想聲明,每一種可能的寵物類型都暗示著相應(yīng)的飼養(yǎng)員類型的存在啥纸,你描述的對(duì)應(yīng)是:
你想要確定的是号杏,對(duì)于每一個(gè)可能的寵物類型,都定義了相應(yīng)的飼養(yǎng)員類型斯棒。但你不需要手動(dòng)操作盾致。你需要一種方法來自動(dòng)定義一組飼養(yǎng)員類型莹妒。
事實(shí)證明,這正是泛型的作用所在!