说明:泛型代码可以让你编写
适用自定义需求以及任意类型
的灵活可重用
的函数
和类型
。
意义:它的可以让你避免重复的代码
,用一种清晰和抽象的方式来表达代码的意图。
23.1 泛型所解决的问题
说明:有了泛型,就不必为各种不同类型重复创建类似的
函数
或类型
。
23.2 泛型函数
说明:
泛型函数
可以适用于任何类型
语法:func 函数名<T>(){...}
- 函数名后面跟着
<占位类型名>
(比如字母T
)来代替实际类型名- 函数被调用时,
T
所代表的类型都会由传入的值的类型推断出来
1 | /***************** 不使用泛型的方法 ****************/ |
23.3 类型参数
说明:类型参数指定并命名一个
占位类型
,并且紧随在函数名后面,使用一对尖括号括起来(例如<T>
)。类型参数
会在函数调用时被实际类型所替换。在泛型函数体
中可以用来
- 定义一个函数的
参数类型
- 作为函数的
返回类型
- 用作函数主体中的
注释类型
23.4 命名类型参数
说明:下面是一些指导性的意见。
- 在大多数情况下,类型参数具有一个
描述性名字
- 当它们之间的关系没有意义时,通常使用
单一的字母
来命名注意:始终使用
大写字母开头的驼峰式命名法
来为类型参数命名,以表明它们是占位类型,而不是一个值。
23.5 泛型类型
说明:除了泛型函数,
Swift
还允许你定义泛型类型。这些自定义类
、结构体
和枚举
可以适用于任何类型
。
1 | /****************** 不使用泛型的结构体 ******************/ |
23.6 扩展一个泛型类型
说明:扩展泛型类型和扩展普通类型类似,特别的地方在于
不需要
在扩展的定义中提供类型参数列表
- 原始类型定义中声明的类型参数列表在扩展中可以直接使用
- 这些来自原始类型中的参数名称会被用作
原始定义中类型参数的引用
1 | // 泛型结构体:栈 |
23.6 类型约束
说明:类型约束可以指定一个
类型参数
必须继承自指定类,或者符合一个特定的协议或协议组合。
23.6.1 类型约束语法
说明:在一个
类型参数名
后面放置一个类名
或者协议名
,通过:
分隔,从而定义类型约束,它们将作为类型参数列表的一部分。
语法:以泛型函数
为例(泛型类型
与此类似)
1 | func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { |
23.6.2 类型约束实践
注意:不是所有的
Swift
类型都可以用等式符==
进行比较。Swift 标准库中定义了一个Equatable
协议,该协议要求任何符合该协议的类型必须实现等式符==
。
扩展:所有的Swift 标准类型
自动支持Equatable
协议
1 | /************ 非泛型 ************/ |
23.7 关联类型
用途:
定义一个协议时
,有的时候声明一个或多个
关联类型作为协议定义的一部分将会,作为一种用来占位
的类型,实现协议是会推断出实际类型
。
说明:关联类型作为协议的一部分,为某个类型提供了一个占位名
(或者说别名),其代表的实际类型在协议被采纳时才会被指定
。
语法:你可以通过typealias
关键字来指定关联类型。
23.7.1 关联类型实践
1 | // 协议 |
23.7.2 通过扩展一个存在的类型来指定关联类型
说明:扩展让一个已存在的类型符合一个协议,其中就包括使用了关联类型的协议。
1 | // 协议:容器 |
23.8 where字句
说明:可以在
参数列表
中通过where
子句为关联类型
定义约束
- 使一个
关联类型
符合某个特定的协议- 使某个特定的类型参数和
关联类型
必须类型相同语法:将
where
关键字紧跟在类型参数列表后面来定义where
子句
where
子句后跟一个或者多个
针对关联类型的约束- 以及
一个或多个
类型参数和关联类型间的相等关系
1 | // 协议:容器 |