2015/6/10

Swift 的 SequenceType、GeneratorType 的實作

class RandomDoubleGenerator: GeneratorType {
    let min = 0.1
    var current = 1.0
    
    func next() -> Double? {
        current = Double(arc4random()) / Double(UINT32_MAX)
        if current < min {
            return nil
        }
        return current
    }
}

class RandomDoubleSequence: SequenceType {
    func generate() -> RandomDoubleGenerator {
        return RandomDoubleGenerator()
    }
}

var sequence = RandomDoubleSequence()
var list = [Double]()
for x in sequence {
    list.append(x)
}
list

var g = sequence.generate()
while let x = g.next(){
    println(x)
}

這裡實作出一個隨機長度的隨機數值序列(Sequence)

這個序列會產出介於0~1之間的亂數

當產出值小於0.1的時候判定為序列結束

大家可以嘗試把上面那段code貼到 playground 看結果


核心程式在 GeneratorType.next()

    func next() -> Double? {
        current = Double(arc4random()) / Double(UINT32_MAX)
        if current < min {
            return nil
        }
        return current
    }
}

為了讓下面的 for 可以跑,我們需要實作一個 SequenceType 和一個GeneratorType

for x in sequence{
    println(x)
}

SequenceType 介面需要實作一個函數 generate()->GeneratorType

他會傳回一個 Generator 作為跑迴圈用的變數

而實作 GeneratorType 需要實作一個函數 next()->T?

若 next() 傳回 nil 就代表結束了,後面沒東西了

其背後的運作邏輯為

var g = sequence.generate()
while let x = g.next(){
    println(x)
}



若對應到C#

Swift 的 SequenceType 其實是 C# 的 IEnumerable

Swift 的 GeneratorType 其實是 C# 的 IEnumerator



附上 SequenceType 和 GeneratorType 合在一起寫的版本:

class RandomDoubleSequence2: GeneratorType, SequenceType
{
    let min = 0.1
    var current = 1.0

    func generate() -> RandomDoubleSequence2 {
        return RandomDoubleSequence2()
    }
    func next() -> Double? {
        current = Double(arc4random()) / Double(UINT32_MAX)
        if current < min {
            return nil
        }
        return current
    }
}

var sequence2 = RandomDoubleSequence2()
var list2 = [Double]()
for x in sequence {
    list2.append(x)
}
list2

沒有留言: