Swift5.3 语言参考(九) 泛型和参数
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9740719.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
本章介绍泛型类型,函数和初始值设定项的参数和参数。声明泛型类型,函数,下标或初始化程序时,可以指定泛型类型,函数或初始化程序可以使用的类型参数。当创建泛型类型的实例或调用泛型函数或初始化程序时,这些类型参数充当占位符,由实际的具体类型参数替换。
有关Swift中泛型的概述,请参阅泛型。
泛型子句
泛型子句指定的通用类型或功能的类型的参数,用这些参数任何相关联的约束和要求沿。泛型参数子句包含在尖括号(<>)中,并具有以下形式:
<generic parameter list>
所述泛型列表是逗号分隔的泛型,其中每一个具有以下形式的列表:
type parameter: constraint
泛型参数由类型参数后跟可选约束组成。甲类型参数是一个简单的占位符类型的名称(例如,T
,U
,V
,Key
,Value
,等等)。您可以在类型,函数或初始化程序声明的其余部分中访问类型参数(及其任何关联类型),包括函数或初始化程序的签名。
该约束指定类型参数从一个特定的类继承或符合一协议或协议的组合物。例如,在下面的泛型函数中,泛型参数指示替换type参数的任何类型参数必须符合协议。T: Comparable
T
Comparable
1 func simpleMax<T: Comparable>(_ x: T, _ y: T) -> T { 2 if x < y { 3 return y 4 } 5 return x 6 }
因为Int
并且Double
,例如,两者都符合Comparable
协议,所以此函数接受任一类型的参数。与泛型类型相比,在使用泛型函数或初始值设定项时,不指定泛型参数子句。相反,类型参数是从传递给函数或初始值设定项的参数类型推断出来的。
1 simpleMax(17, 42) // T is inferred to be Int 2 simpleMax(3.14159, 2.71828) // T is inferred to be Double
where
子句
您可以通过where
在类型或函数体的开始大括号之前包含泛型子句来指定类型参数及其关联类型的其他要求。泛型where
子句由where
关键字组成,后跟逗号分隔的一个或多个需求列表。
where requirements
泛型子句中的要求where
指定类型参数继承自类或符合协议或协议组合。尽管generic where
子句为表达类型参数的简单约束提供了语法糖(例如,等同于等等),但您可以使用它来为类型参数及其关联类型提供更复杂的约束。例如,您可以约束类型参数的关联类型以符合协议。例如,指定符合协议并且关联类型符合协议。该约束确保序列的每个元素是等同的。
<T: Comparable><T> where T: Comparable<S: Sequence> where S.Iterator.Element: EquatableSSequenceS.Iterator.ElementEquatable
您还可以使用==
运算符指定两种类型相同的要求。例如,表达符合协议的约束,并且两个序列的元素必须属于同一类型。
<S1: Sequence, S2: Sequence> where S1.Iterator.Element == S2.Iterator.ElementS1S2Sequence
替换类型参数的任何类型参数必须满足对type参数的所有约束和要求。
您可以通过在类型参数上提供不同的约束,要求或两者来重载泛型函数或初始化程序。当您调用重载的泛型函数或初始化程序时,编译器使用这些约束来解析要调用的重载函数或初始化程序。
有关泛型where
子句的更多信息以及查看泛型函数声明中的一个示例,请参阅Generic Where子句。
1 GRAMMAR OF A GENERIC PARAMETER CLAUSE 2 3 generic-parameter-clause → < generic-parameter-list > 4 5 generic-parameter-list → generic-parameter | generic-parameter , generic-parameter-list 6 7 generic-parameter → type-name 8 9 generic-parameter → type-name : type-identifier 10 11 generic-parameter → type-name : protocol-composition-type 12 13 generic-where-clause → where requirement-list 14 15 requirement-list → requirement | requirement , requirement-list 16 17 requirement → conformance-requirement | same-type-requirement 18 19 conformance-requirement → type-identifier : type-identifier 20 21 conformance-requirement → type-identifier : protocol-composition-type 22 23 same-type-requirement → type-identifier == type
参数子句
一个一般的参数子句指定泛型类型的类型参数。泛型参数子句包含在尖括号(<>)中,并具有以下形式:
1 <generic argument list>
在一般的参数列表是一个逗号分隔的类型参数列表。甲类型参数是一个实际的具体类型,它取代一个通用类型的泛型子句中相应类型的参数的名称。结果是该泛型类型的专用版本。下面的示例显示了Swift标准库的通用字典类型的简化版本。
1 struct Dictionary<Key: Hashable, Value>: Collection, ExpressibleByDictionaryLiteral { 2 /* ... */ 3 }
泛型Dictionary
类型的专用版本是通过替换泛型参数和具体类型参数和形成的。每个类型参数必须满足它替换的泛型参数的所有约束,包括泛型子句中指定的任何其他要求。在上面的示例中,类型参数被约束为符合协议,因此也必须符合协议。Dictionary<String, Int>
Key: Hashable
Value
String
Int
where
Key
Hashable
String
Hashable
您还可以使用类型参数替换类型参数,该类型参数本身是泛型类型的专用版本(前提是它满足适当的约束和要求)。例如,可以替换类型参数Element
在Array<Element>
与阵列的专用版本,Array<Int>
以形成一个数组,其元素本身整数数组。
let arrayOfArrays: Array<Array<Int>> = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
如泛型子句中所述,您不使用泛型参数子句来指定泛型函数或初始化器的类型参数。
1 GRAMMAR OF A GENERIC ARGUMENT CLAUSE 2 3 generic-argument-clause → < generic-argument-list > 4 5 generic-argument-list → generic-argument | generic-argument , generic-argument-list 6 7 generic-argument → type