泛型代码让你能够根据自定义的需求,编写出适用于任意类型、灵活可重用的函数及类型。它能让你避免代码的重复,用一种清晰和抽象的方式来表达代码的意图。
泛型函数
泛型类型
除了泛型函数,Swift 还允许你定义泛型类型。这些自定义类、结构体和枚举可以适用于任何类型,类似于Array和Dictionary。
扩展一个泛型类型
当你扩展一个泛型类型的时候,你并不需要在扩展的定义中提供类型参数列表。原始类型定义中声明的类型参数列表在扩展中可以直接使用,并且这些来自原始类型中的参数名称会被用作原始定义中类型参数的引用。
类型约束
swapTwoValues(_:_:)函数和Stack类型可以作用于任何类型。不过,有的时候如果能将使用在泛型函数和泛型类型中的类型添加一个特定的类型约束,将会是非常有用的。类型约束可以指定一个类型参数必须继承自指定类,或者符合一个特定的协议或协议组合。
例如,Swift 的Dictionary类型对字典的键的类型做了些限制。在字典的描述中,字典的键的类型必须是可哈希(hashable)的。也就是说,必须有一种方法能够唯一地表示它。Dictionary的键之所以要是可哈希的,是为了便于检查字典是否已经包含某个特定键的值。若没有这个要求,Dictionary将无法判断是否可以插入或者替换某个指定键的值,也不能查找到已经存储在字典中的指定键的值。
为了实现这个要求,一个类型约束被强制加到Dictionary的键类型上,要求其键类型必须符合Hashable协议,这是 Swift 标准库中定义的一个特定协议。所有的 Swift 基本类型(例如String、Int、Double和Bool)默认都是可哈希的。
当你创建自定义泛型类型时,你可以定义你自己的类型约束,这些约束将提供更为强大的泛型编程能力。抽象概念,例如可哈希的,描述的是类型在概念上的特征,而不是它们的显式类型。
关联类型
定义一个协议时,有的时候声明一个或多个关联类型作为协议定义的一部分将会非常有用。关联类型为协议中的某个类型提供了一个占位名(或者说别名),其代表的实际类型在协议被采纳时才会被指定。你可以通过associatedtype关键字来指定关联类型。
Where 子句
类型约束让你能够为泛型函数或泛型类型的类型参数定义一些强制要求。