Swift:Generators 與 Sequences 淺析

// 《Functional Programming in Swift》Ch11 Notes

本書購買連接 http://www.objc.io/books/數組

前言

GeneratorsSequences構成了Swift式循環。函數

Generators

提到數組咱們就會想到遍歷,通常的遍歷可能都是從頭至尾進行的。可是若是你有特殊的需求呢。你可能不想呆板的進行遍歷。這時候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

Sequences

Generators在循環過程當中每一個元素提供的服務是一次性的。因此咱們想作倒回操做的話須要生成一個新的generator。若不想這樣則須要用上sequence,其聽從另一個協議SequenceTypeit

怎麼玩

protocol SequenceType {
    typealias Generator: GeneratorType 
    func generate() -> Generator
}

經過協議咱們知道每一個sequence都與一個generator類型已經一個generator構造器綁定在一塊兒。咱們可使用這個遍歷sequenceio

舉個栗子,咱們可使用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,提高代碼的統一性。

相關文章
相關標籤/搜索