Swift中的生成器和序列
前言
生成器(Generators)与序列(Sequences)构成了Swift式循环。
生成器(Generators)
提到数组我们就会想到遍历,一般的遍历可能都是从头到尾进行的。但是如果你有特殊的需求呢。你可能不想呆板的进行遍历。这时候Generators就可以派上用场了。
Generators的存在是进行特殊癖好的数组遍历,其筛选出符合该癖好的下标索引到数组没有元素为止。
任意一个generator都需要遵从如下协议:
1 | protocol GeneratorType { |
根据上述协议,该协议需要元素类型以及一个next()函数。
举个倒序索引的generator:
1 | class CountdownGenerator: GeneratorType { |
输出:
Element 2 of the array is C
Element 1 of the array is B
Element 0 of the array is A
优点:
尽管这个小例子看起来有点小题大做,可生成器却封装了数组序列值的计算。如果你想要用另一种方式排序序列值,我们只需要更新生成器,而不必再修改这里的代码。
序列(Sequences)
Generators在循环过程中每个元素提供的服务是一次性的。所以我们想做倒回操作的话需要生成一个新的generator。若不想这样则需要用上sequence,其遵从另外一个协议SequenceType:
1 | protocol SequenceType { |
通过协议我们知道每个sequence都与一个generator类型已经一个generator构造器绑定在一起。我们可以使用这个遍历sequence。
举个栗子,我们可以使用CountdownGenerator来定义一个sequence从而生成一个倒序的数组。
1 | struct ReverseSequence<T>: SequenceType { |
输出:
Index 2 is C
Index 1 is B
Index 0 is A
Swift在处理序列时有一个特别的语法。不同于创建一个序列的关联生成器,你可以编写一个for-in循环。比如,我们也可以将上面的代码段写成这样:
1 | for i in ReverseSequence(array: xs) { |
输出:
Index 2 is C
Index 1 is B
Index 0 is A
实际上,Swift做的只是使用generate方法生成了一个生成器,然后重复地调用其next函数直到返回nil。
优点:
对比之前仅仅使用生成器的例子,同一个序列可以被第二次遍历–为此我们只需要调用generate来生成一个新的生成器就可以了。