Swift泛型形參子句
泛型形參子句
泛型形參子句指定泛型類型或函數的類型形參,以及這些參數的關聯約束和要求。泛型形參子句用尖括號(<>)包住,並且有以下兩種形式:
<generic parameter list
>
<generic parameter list
whererequirements
>
泛型形參列表中泛型形參用逗號分開,每一個采用以下形式:
type parameter
:constrain
泛型形參由兩部分組成:類型形參及其後的可選約束。類型形參隻是占位符類型(如T,U,V,KeyType,ValueType等)的名字而已。你可以在泛型類型、函數的其餘部分或者構造器聲明,以及函數或構造器的簽名中使用它。
約束用於指明該類型形參繼承自某個類或者遵守某個協議或協議的一部分。例如,在下麵的泛型中,泛型形參T: Comparable
表示任何用於替代類型形參T
的類型實參必須滿足Comparable
協議。
func simpleMin<T: COmparable>(x: T, y: T) -> T {
if x < y {
return y
}
return x
}
如,Int
和Double
均滿足Comparable
協議,該函數接受任何一種類型。與泛型類型相反,調用泛型函數或構造器時不需要指定泛型實參子句。類型實參由傳遞給函數或構造器的實參推斷而出。
simpleMin(17, 42) // T is inferred to be Int
simpleMin(3.14159, 2.71828) // T is inferred to be Double
Where 子句
要想對類型形參及其關聯類型指定額外要求,可以在泛型形參列表之後添加where
子句。where
子句由關鍵字where
及其後的用逗號分割的多個要求組成。
where
子句中的要求用於指明該類型形參繼承自某個類或遵守某個協議或協議的一部分。儘管where
子句有助於表達類型形參上的簡單約束(如T: Comparable
等同於T where T: Comparable
,等等),但是依然可以用來對類型形參及其關聯約束提供更複雜的約束。如,<T where T: C, T: P>
表示泛型類型T
繼承自類C
且遵守協議P
。
如上所述,可以強製約束類型形參的關聯類型遵守某個協議。<T: Generator where T.Element: Equatable>
表示T
遵守Generator
協議,而且T
的關聯類型T.Element
遵守Eauatable
協議(T
有關聯類型是因為Generator
聲明了Element
,而T
遵守Generator
協議)。
也可以用操作符==
來指定兩個類型等效的要求。例如,有這樣一個約束:T
和U
遵守Generator
協議,同時要求它們的關聯類型等同,可以這樣來表達:<T: Generator, U: Generator where T.Element == U.Element>
。
當然,替代類型形參的類型實參必須滿足所有類型形參所要求的約束和要求。
泛型函數或構造器可以重載,但在泛型形參子句中的類型形參必須有不同的約束或要求,抑或二者皆不同。當調用重載的泛型函數或構造器時,編譯器會用這些約束來決定調用哪個重載函數或構造器。
泛型類可以生成一個子類,但是這個子類也必須是泛型類。
泛型形參子句語法
泛型參數子句 → < 泛型參數列表 約束子句 可選 >
泛型參數列表 → 泛形參數 | 泛形參數 , 泛型參數列表
泛形參數 → 類型名稱
泛形參數 → 類型名稱 : 類型標識
泛形參數 → 類型名稱 : 協議合成類型
約束子句 → where 約束列表
約束列表 → 約束 | 約束 , 約束列表
約束 → 一致性約束 | 同類型約束
一致性約束 → 類型標識 : 類型標識
一致性約束 → 類型標識 : 協議合成類型
同類型約束 → 類型標識 == 類型標識