范型可以说是 Swift 跟 OC 相比最大的优势了。通过给像集合这类东西关联范型, 可以写出更可预测并且更安全的代码。在 Swift4 中类型约束更为强大, 它能够让我们更能够轻而易举的做很多事情。即使是通用代码, 也能充分的利用 Swift 的类型系统。
例1:
首先我们来看看一个简单的例子。比如说给一个数字数字求和。我们可能会些这样的代码:
|
|
使用范型约束, 我们可以这样来实现这个需求:
|
|
两者相比, 使用范型约束最大的优势是使用扩展, 能够让这个功能跟调用者更紧密。比较一下:
|
|
在 OC 里面, 可能有些同学会写一个 XXXTool
之类的类, 来封装这种类型的功能。 或者是直接写成 C 的函数。但是不论怎么写, 这样貌似都不是特别的 OOP。或者OC 还可以直接给 NSArray 加一个 category, 然后再实现相似的功能。但是, 这样做不就等于所有的 array 都具有这个功能了吗?
例2
再来看这样的需求: 计算某个包含字符串集合中有多少个单词。我们可以通过给集合添加一个扩展轻松的完成这件事情。给 Collection
添加一个约束, 限制集合中的 Element
是 String
类型:
|
|
还有一个很酷的做法是约束集合类型中的 Element
是 Closure
:
|
|
例3
还有一个很好用的特性是使用协议定义 API 的时候。这几乎是写可测试代码以及功能解耦的最佳实践了。需要注意的是, 在需要灵活使用嵌套类型的时候, 这可能会有点麻烦。
看例子吧!我们经常都想要定义一些通用的 API, 来管理程序中的各种 model。这时候肯定会想要定义一个协议:
|
|
现在我们再来定一个查找符合某个条件的方法:传入某个查询条件, 然后返回符合这个条件的模型数组。
|
|
这个时候, 这个协议变成了这样。这个样子依然有问题,不够灵活, 而且还有一个很恐怖的问题: 硬编码。接下来我们试着使用范型约束来使用 Swift 的类型系统, 让这个功能更灵活, 并且使用类型系统来解决硬编码的问题。
接下来, 再给 ModelManager
关联两个类型, Query
和 Collection
。Query
用来描述查询的条件。他可以是任何东西, 只要能够描述查询条件就可以。当然, 个人认为可能 enum 是最好的选择。Collection
用来描述查询结果, 他用来限制返回的结果就是这个管理类的模型。现在这个协议就成这样了:
|
|
有了上面的基础, 就可以很方便的实现一些具有查询功能的模型管理类了。比如说我们要用户管理类, 需要通过用户姓名和年龄段来查询符合要求的用户:
|
|
对有些模型来说, 使用字典来作为返回的 Collection
可能是更好的方法。下面这个例子是用来通过影片名称和导演名字来筛选电影的例子。返回的结果通过电影分类来做分类。
|
|
使用范型约束能够很容易的进行面向协议编程(POP)。