Swift學習筆記 三十五 泛型 下

2021-09-26 09:23:14 字數 2803 閱讀 9927

定義乙個協議時,宣告乙個或多個關聯型別作為協議定義的一部分將會非常有用。關聯型別為協議中的某個型別提供了乙個佔位

符名稱,其代表的實際型別在協議被遵循時才會被指定。關聯型別通過 associatedtype 關鍵字來指定。

下⾯例子定義了乙個 container 協議,該協議定義了乙個關聯型別 item :

protocol container

subscript(i: int) -> item

container 協議定義了三個任何遵循該協議的型別(即容器)必須提供的功能:

2.必須可以通過 count 屬性獲取容器中元素的數量,並返回乙個 int 值。

3.必須可以通過索引值型別為 int 的下標檢索到容器中的每乙個元素。

該協議沒有指定容器中元素該如何儲存以及元素型別。該協議只指定了任何遵從 container 協議的型別必須提供的三個功能。遵

從協議的型別在滿足這三個條件的情況下,也可以提供其他額外的功能。

任何遵從 container 協議的型別必須能夠指定其儲存的元素的型別。具體來說,它必須確保新增到容器內的元素以及下標返回的

元素型別是正確的。

為了定義這些條件, container 協議需要在不知道容器中元素的具體型別的情況下引用這種型別。 container 協議 需要指定任何

為此, container 協議宣告了乙個關聯型別 item ,寫作 associatedtype item 。協議沒有定義 item 是什麼,這個資訊留給遵從協

從⽽保證任何 container 的⾏為都能如預期。

這是前面非泛型版本 intstack 型別,使其遵循 container 協議:

struct intstack: container 

container 來使用。

你可以在協議⾥給關聯型別新增約束來要求遵循的型別滿足約束。例如,下面的**定義了 container 協議, 要求關聯型別 item 

必須遵循 equatable 協議:

protocol container

subscript(i: int) -> item

要遵守 container 協議, item 型別也必須遵守 equatable 協議。

協議可以作為它自身的要求出現。例如,有乙個協議細化了 container 協議,新增了乙個 suffix(_:) ⽅法。 suffix(_:) ⽅法返回容

器中從後往前給定數量的元素,並把它們儲存在乙個 suffix 型別的實例里。

protocol suffixablecontainer: container else else

var notequatablestack = stack()

let notequatablevalue = notequatable()

notequatablestack.push(notequatablevalue)

notequatablestack.istop(notequatablevalue)    // 報錯

你可以使用泛型 where ⼦句去擴充套件乙個協議。基於以前的示例,下面的示例擴充套件了 container 協議,新增乙個startswith(_:) 方

法。extension container where item: equatable else

subscript(i: int) -> item

associatedtype iterator: iteratorprotocol where iterator.element == item

func makeiterator() -> iterator

迭代器( iterator )的泛型 where 子句要求:無論迭代器是什麼型別,迭代器中的元素型別,必須和容器專案的型別保持一致。 

makeiterator() 則提供了容器的迭代器的訪問介面。

⼀個協議繼承了另乙個協議,你通過在協議宣告的時候,包含泛型 where ⼦句,來新增了乙個約束到被繼承協議的關聯型別。例

如,下⾯的**宣告了乙個 comparablecontainer 協議,它要求所有的 item 必須是 comparable 的。

protocol comparablecontainer: container where item: comparable

下標可以是泛型,它們能夠包含泛型 where ⼦句。你可以在 subscript 後用尖括號來寫佔位符型別,你還可以在下標**塊花

括號前寫 where ⼦句。例如:

extension container {

subscript(indices: indices) -> [item]

where indices.iterator.element == int {

var result = [item]()

for index in indices {

這個 container 協議的擴充套件新增了乙個下標方法,接收乙個索引的集合,返回每乙個索引所在的值的陣列。這個泛型下標的約束

如下:1.在尖括號中的泛型引數 indices ,必須是符合標準庫中的 sequence 協議的型別。

2.下標使用的單一的引數, indices ,必須是 indices 的實例。

3.泛型 where 子句要求 sequence(indices) 的迭代器,其所有的元素都是 int 型別。這樣就能確保在序列 ( sequence )中的索

引和容器( container )⾥面的索引型別是一致的。

綜合一下,這些約束意味著,傳入到 indices 下標,是乙個整型的序列。

Swift學習筆記系列 (23)泛型

tags swift 學習筆記 感慨一下 泛型這一章很亂,很零碎,很難總結。避免重複 增加靈活性 所有型別 泛型是另外一種引數,引數表示的是型別,泛型小可以用在函式上,大可用在型別定義上。這裡 型別 不包括協議,協議定義不能直接採用泛型,可以採用關聯型別。函式引數的型別也是引數的函式叫做泛型函式。這...

swift 筆記 二十 泛型

泛型 泛型是為了解決在針對不同資料型別,而做了同一種功能的操作導致的每個型別我們都要寫乙份 的問題。有了泛型,我們可以只寫乙份邏輯 而適應於不同的資料型別。func swapint inout num1 int,inout num2 int func swapdouble inout num1 do...

swift 筆記 二十 泛型

泛型 泛型是為了解決在針對不同資料型別。而做了同一種功能的操作導致的每乙個型別我們都要寫乙份 的問題。有了泛型,我們能夠僅僅寫乙份邏輯 而適應於不同的資料型別。func swapint inout num1 int,inout num2 int func swapdouble inout num1 ...