为有牺牲多壮志,敢教日月换新天。

Swift5.3 语言参考(九) 泛型和参数

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9740719.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

本章介绍泛型类型,函数和初始值设定项的参数和参数。声明泛型类型,函数,下标或初始化程序时,可以指定泛型类型,函数或初始化程序可以使用的类型参数。当创建泛型类型的实例或调用泛型函数或初始化程序时,这些类型参数充当占位符,由实际的具体类型参数替换。

有关Swift中泛型的概述,请参阅泛型

泛型子句

泛型子句指定的通用类型或功能的类型的参数,用这些参数任何相关联的约束和要求沿。泛型参数子句包含在尖括号(<>)中,并具有以下形式:

<generic parameter list>

所述泛型列表是逗号分隔的泛型,其中每一个具有以下形式的列表:

type parameter: constraint

泛型参数由类型参数后跟可选约束组成类型参数是一个简单的占位符类型的名称(例如,TUVKeyValue,等等)。您可以在类型,函数或初始化程序声明的其余部分中访问类型参数(及其任何关联类型),包括函数或初始化程序的签名。

约束指定类型参数从一个特定的类继承或符合一协议或协议的组合物。例如,在下面的泛型函数中,泛型参数指示替换type参数的任何类型参数必须符合协议。T: ComparableTComparable

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: HashableValueStringIntwhereKeyHashableStringHashable

您还可以使用类型参数替换类型参数,该类型参数本身是泛型类型的专用版本(前提是它满足适当的约束和要求)。例如,可以替换类型参数ElementArray<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

 

posted @ 2018-10-03 20:00  为敢技术  阅读(1109)  评论(0编辑  收藏  举报