Swift語法——Swift Sequences 探究

今天看到Array 的API中有這麼一個聲明的函數:

    mutating func extend<S : SequenceType where T == T>(newElements: S)

函數名爲extend, 所需參數是S類型的newElements, 而S首先要實現SequenceType協議。那SequenceType到底是什麼呢?

官方對SequenceType的聲明API如下:

protocol SequenceType : _Sequence_Type {

    /// A type that provides the *sequence*\ 's iteration interface and
    /// encapsulates its iteration state.
    typealias Generator : GeneratorType

    /// Return a *generator* over the elements of this *sequence*.
    ///
    /// Complexity: O(1)
    func generate() -> Generator
}

裏面需要實現一個函數generate(),返回了一個GeneratorType類型,GeneratorType又是什麼呢?看看APT

protocol GeneratorType {

    /// The type of element generated by `self`.
    typealias Element

    /// Advance to the next element and return it, or `nil` if no next
    /// element exists.
    ///
    /// Requires: `next()` has not been applied to a copy of `self`
    /// since the copy was made, and no preceding call to `self.next()`
    /// has returned `nil`.  Specific implementations of this protocol
    /// are encouraged to respond to violations of this requirement by
    /// calling `preconditionFailure("...")`.
    mutating func next() -> Element?
}

GeneratorType必須要實現一個函數next(),它的作用就是返回一個Element,註釋裏說的很清楚:它的作用就是一直返回元素,直到最後。

具體怎麼用呢,咱們從for...in...來了解下:


首先讓我們先來看一下常見的這個遍歷方法:

for x in mySequence {
    // iterations here
}

而Swift實際上是按照下面這個方法來實現的:

var __g: Generator = mySequence.generate()
while let x = __g.next() {
    // iterations here
}

這是什麼意思呢?

1)Swift調用generate()來生成了一個Generator,這個對象是 一個私有的變量即__g;

2) __g調用了next()函數,返回了一個optional類型對象element?。這個對象element被解包後賦值給了x;

3)通過next()函數一直來獲取下一個元素,直到爲nil停止。


所以,要實現Sequence必須要先有一個Generator。如下面的例子是對數組進行倒序索引:

1) 先聲明繼承與GeneratorType的類,實現Element和next()

///GeneratorType
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--
    }
}
2)完成繼承於SequenceType的類,實現Generator和generate()

class ReverseSequence<T>: SequenceType {
    typealias Generator = CountdownGenerator
    
    var array: [T]
    
    init(array: [T]){
        self.array = array
    }
    
    func generate() -> Generator {
        return CountdownGenerator(array: array)
    }
}

3)使用:

        let array = ["a", "b", "c"]
        
        for i in ReverseSequence(array: array){
            println("索引\(i)的值是:\(array[i])")
        }

結果:

索引2的值是:c
索引1的值是:b
索引0的值是:a


參考資料:http://segmentfault.com/a/1190000002464158

Generator





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章