// 《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,提高代碼的統一性。