// 《Functional Programming in Swift》Ch11 Notes
本书购买连接 http://www.objc.io/books/数组
Generators
与Sequences
构成了Swift式循环。函数
提到数组咱们就会想到遍历,通常的遍历可能都是从头至尾进行的。可是若是你有特殊的需求呢。你可能不想呆板的进行遍历。这时候Generators
就能够派上用场了。oop
一个字:Generators的存在是进行特殊癖好的数组遍历,其筛选出符合该癖好的下标索引到数组没有元素为止。code
任意一个generator都须要听从以下协议:索引
protocol GeneratorType { typealias Element func next() -> Element? }
根据上述协议,该协议须要元素类型以及一个next()
函数。element
举个倒序索引的generator:get
class CountdownGenerator: GeneratorType { typealias Element = Int var element: Element init<T>(array: [T]) { self.element = array.count - 1 } func next() -> Element? { return self.element < 0 ? nil : element-- } } // TEST CASE let xs = ["A", "B", "C"] let generator = CountdownGenerator(array: xs) while let i = generator.next() { println("Element \(i) of the array is \(xs[i])") }
好处是啥,个人总结是把一个很抽象遍历模式使用Generators
的方式剥离出来,当你对当前的迭代循环方式不爽的时候只须要修改一下当前的这个generator
。更直观的“头疼医头,脚疼医脚”。generator
Generators
在循环过程当中每一个元素提供的服务是一次性的。因此咱们想作倒回操做的话须要生成一个新的generator
。若不想这样则须要用上sequence
,其听从另一个协议SequenceType
:it
protocol SequenceType { typealias Generator: GeneratorType func generate() -> Generator }
经过协议咱们知道每一个sequence
都与一个generator
类型已经一个generator
构造器绑定在一块儿。咱们可使用这个遍历sequence
。io
举个栗子,咱们可使用CountdownGenerator
来定义一个sequence
从而生成一个倒序的数组。
struct ReverseSequence<T>: SequenceType { var array: [T] init(array: [T]) { self.array = array } typealias Generator = CountdownGenerator func generate() -> Generator { return CountdownGenerator(array: array) } } // TEST CASE let xs = ["A", "B", "C"] let reverseSequence = ReverseSequence(array: xs) let reverseGenerator = reverseSequence.generate() while let i = reverseGenerator.next() { println("Index \(i) is \(xs[i])") } // 利用熟悉的OO for i in ReverseSequence(array: xs) { println("Index \(i) is \(xs[i])") }
不用每次进行Loop操做的时候都去生成一个新的generator,提高代码的统一性。