How is a type-erased generic wrapper implemented?

后端 未结 2 1663
渐次进展
渐次进展 2021-01-01 05:37

I need to implement a type-erasing wrapper for my own structure, very similar to SequenceOf, GeneratorOf, etc. So I started by trying to just re-im

2条回答
  •  感情败类
    2021-01-01 06:25

    Here is a sample implementation of MySequenceOf which seems to work:

    struct MySequenceOf : SequenceType {
    
        let myGenerator : GeneratorOf
    
        init(_ makeUnderlyingGenerator: () -> G) {
            self.myGenerator = GeneratorOf( makeUnderlyingGenerator() )
        }
    
        init(_ base: S) {
            self.myGenerator = GeneratorOf( base.generate() )
        }
    
        func generate() -> GeneratorOf {
            return myGenerator
        }
    }
    

    Example usage:

    let seq = MySequenceOf {
        _ -> GeneratorOf in
        var i = 0
        return GeneratorOf {
            i < 5 ? ++i : nil
        }
    }
    for i in seq  { println(i) }
    

    You can also replace GeneratorOf from the Swift library by the following MyGeneratorOf:

    struct MyGeneratorOf : GeneratorType, SequenceType {
    
        var nextFunc : () -> T?
    
        init(_ base: G) {
            self.nextFunc = {
                () -> T? in
                var generator = base
                return generator.next()
            }
        }
    
        init(_ nextElement: () -> T?) {
            self.nextFunc = nextElement
        }
    
        mutating func next() -> T? {
            return nextFunc()
        }
    
        // Returns a copy of itself.
        func generate() -> MyGeneratorOf {
            return MyGeneratorOf(nextFunc)
        }
    
    }
    

    So (as far as I understand it, and I am far from understanding all the generic sequence and generator stuff) the "trick" is that the next() method of the generator is a closure which captures the given generator and therefore can forward the next() call. A cast is not necessary.

提交回复
热议问题