幫助 protocol 實現型別代號的 Associated Type

Swift 裡很多東西都可以 generic,除了我們熟悉的 generic type & generic function 外,還有我們本篇文章的主角 generic protocol。

protocol 可以透過 Associated Type 宣告類似 generic 的型別代號,代號的真正型別則由到時候遵從 protocol 的型別決定。如此我們將能寫出更彈性的程式碼,不用一開始就將 protocol 裡 function 的參數型別限定。(ps: protocol with associated type 的縮寫是 PAT)

比方我們看看以下例子 :

protocol Princess {
associatedtype HandyMan
func buyFoodForMe(boyFriend:HandyMan)
}

在 protocol Princess 裡,我們利用關鍵字 associatedtype 宣告型別代號 HandyMan。HandyMan 就是所謂的工具人,當公主肚子餓時,她將呼叫 function buyFoodForMe,傳入型別工具人的男朋友,請男朋友買吃的給她。

class TaiwanPrince {
func buyFoodForMyPrincess() {
print("珍珠奶茶")
}
}

class BeautifulPrincess:Princess {
func buyFoodForMe(boyFriend:TaiwanPrince) {
boyFriend.buyFoodForMyPrincess()
}
}

每個公主喜歡的菜都不一樣,我們可以定義不同的公主型別,讓它們交不同的男朋友。像美麗的公主,一般都喜歡台灣的王子。因此我們定義遵從 protocol Princess 的類別 BeautifulPrincess,定義 function buyFoodForMe。這時候神奇的事就發生了 ! 當我們定義 buyFoodForMe 的參數 boyFrined 型別為 TaiwanPrince 時,Swift 很聰明,它知道 buyFoodForMe(boyFriend:TaiwanPrince) 對應到當初 protocol 裡宣告的 buyFoodForMe(boyFriend:HandyMan),所以型別代號 HandyMan 其實是 TaiwanPrince。因此,之後能夠買食物給美麗公主的男朋友,只能是來自台灣的王子。

如以下例子所示,童話故事的結局都是美好的,最後溫蒂將開心地吃到彼得潘精心準備的珍珠奶茶。

var wendy = BeautifulPrincess()
var peterPan = TaiwanPrince()
wendy.buyFoodForMe(boyFriend: peterPan)

前面說完了美麗公主的故事,接著我們要公平,關心一下邪惡的公主。如以下例子所示,邪惡公主 EvilPrincess 將 function buyFoodForMe 的 boyFriend 參數型別定義為 Monster,所以她這輩子只能跟怪獸交往,到時候 protocol 裡的型別代號 HandyMan 也就變成了 Monster。

class Monster {
func buyFoodForMyPrincess() {
print("我很醜,可是我有很好吃的食物")
}
}

class EvilPrincess:Princess {
func buyFoodForMe(boyFriend:Monster) {
boyFriend.buyFoodForMyPrincess()
}
}

決定 associated type 型別的六種方法

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com