類型約束中描述的類型約束確保你定義關(guān)于類型參數(shù)的需求和一泛型函數(shù)或類型有關(guān)聯(lián)。
對(duì)于關(guān)聯(lián)類型的定義需求也是非常有用的。你可以通過這樣去定義where語句作為一個(gè)類型參數(shù)隊(duì)列的一部分。一個(gè)where語句使你能夠要求一個(gè)關(guān)聯(lián)類型遵循一個(gè)特定的協(xié)議,以及(或)那個(gè)特定的類型參數(shù)和關(guān)聯(lián)類型可以是相同的。你可寫一個(gè)where語句,通過緊隨放置where關(guān)鍵字在類型參數(shù)隊(duì)列后面,其后跟著一個(gè)或者多個(gè)針對(duì)關(guān)聯(lián)類型的約束,以及(或)一個(gè)或多個(gè)類型和關(guān)聯(lián)類型的等于關(guān)系。
下面的列子定義了一個(gè)名為allItemsMatch的泛型函數(shù),用來檢查是否兩個(gè)Container單例包含具有相同順序的相同元素。如果匹配到所有的元素,那么返回一個(gè)為true的Boolean值,反之,則相反。
這兩個(gè)容器可以被檢查出是否是相同類型的容器(雖然它們可以是),但它們確實(shí)擁有相同類型的元素。這個(gè)需求通過一個(gè)類型約束和where語句結(jié)合來表示:
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
// check that both containers contain the same number of items
if someContainer.count != anotherContainer.count {
return false
}
// check each pair of items to see if they are equivalent
for i in 0..someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// all items match, so return true
return true
}
這個(gè)函數(shù)用了兩個(gè)參數(shù):someContainer和anotherContainer。someContainer參數(shù)是類型C1,anotherContainer參數(shù)是類型C2。C1和C2是容器的兩個(gè)占位類型參數(shù),決定了這個(gè)函數(shù)何時(shí)被調(diào)用。
這個(gè)函數(shù)的類型參數(shù)列緊隨在兩個(gè)類型參數(shù)需求的后面:
C1必須遵循Container協(xié)議 (寫作 C1: Container)。C2必須遵循Container協(xié)議 (寫作 C2: Container)。C1的ItemType同樣是C2的ItemType(寫作 C1.ItemType == C2.ItemType)。C1的ItemType必須遵循Equatable協(xié)議 (寫作 C1.ItemType: Equatable)。
第三個(gè)和第四個(gè)要求被定義為一個(gè)where語句的一部分,寫在關(guān)鍵字where后面,作為函數(shù)類型參數(shù)鏈的一部分。
這些要求意思是:
someContainer是一個(gè)C1類型的容器。 anotherContainer是一個(gè)C2類型的容器。 someContainer和anotherContainer包含相同的元素類型。 someContainer中的元素可以通過不等于操作(!=)來檢查它們是否彼此不同。
第三個(gè)和第四個(gè)要求結(jié)合起來的意思是anotherContainer中的元素也可以通過 != 操作來檢查,因?yàn)樗鼈冊(cè)?code style="box-sizing: border-box; -webkit-tap-highlight-color: transparent; -webkit-font-smoothing: antialiased; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; font-size: 14px; padding: 0px 5px; color: rgb(199, 37, 78); background-color: rgb(248, 248, 248); white-space: nowrap; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; margin: 0px 2px; border: 1px solid rgb(234, 234, 234);">someContainer中元素確實(shí)是相同的類型。
這些要求能夠使allItemsMatch函數(shù)比較兩個(gè)容器,即便它們是不同的容器類型。
allItemsMatch首先檢查兩個(gè)容器是否擁有同樣數(shù)目的items,如果它們的元素?cái)?shù)目不同,沒有辦法進(jìn)行匹配,函數(shù)就會(huì)false。
檢查完之后,函數(shù)通過for-in循環(huán)和半閉區(qū)間操作(..)來迭代someContainer中的所有元素。對(duì)于每個(gè)元素,函數(shù)檢查是否上一篇:Swift 協(xié)議下一篇:Swift構(gòu)造器