C/C++ 生成器

准备研究

JavaScript 的生成器

JavaScript 中的生成器可以用闭包和yield 生成。

用类实现生成器,实现斐波那切序列。

//类实现生成器
var Fab = function (){
    this.a = 0;
    this.b = 1;
    
    this.next = function(){
        var temp = this.b;
        this.b = this.a + this.b;
        this.a = temp;
        return temp;
    };
};
var g= new Fab();
console.log(g.next(), g.next(),g.next(),g.next());                            
                        

闭包类似其他高级语言的类,成员变量在Javascript 中表现为局部变量。以斐波那契序列为例。

//闭包实现生成器 斐波那契
var fab = function(){
    var a = 0;
    var b = 1;
    return {
        next:function(){
            var result = b;
            b = a + b;
            a = result;           
            return result;
        },
    };
};                            
                        

用yield 实现生成器。

yield关键字使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

yield关键字实际返回一个IteratorResult对象,它有两个属性,value和done。value属性是对yield表达式求值的结果,而done是false,表示生成器函数尚未完全完成。

一旦遇到 yield 表达式,生成器的代码将被暂停运行,直到生成器的 next() 方法被调用。每次调用生成器的next()方法时,生成器都会恢复执行,直到达到以下某个值。

参考 JavaScript | MDN yield JavaScript | MDN 迭代器和生成器

// yield 表达式用于委托给另一个generator 或可迭代对象。
var generator = function*(max){
    var a = 0;
    var b = 1;
    var n = 0;

    while(n < max){
        var temp = b;
        yield temp;
        b = a + b;
        a = temp;
        n = n + 1;
    }    
};
var g =generator(11);
console.log(g.next(), g.next(),g.next(),g.next());
var r = g.next();
while(r["done"]==false){
    console.log(r["value"]);
    r = g.next();
} 
                        

PowerShell 的生成器

研究中...

Python 生成器

跟 JavaScript 类似,可以通过类和 yield 来实现。参考 Python yield 使用浅析-廖雪峰

类实现生成器。

#类实现生成器,需要定义 __iter__ 和 next 函数
class Fab(object):
    def __init__(self,max):
        self.max = max
        self.n = 0
        self.a = 0
        self.b = 1

    def __iter__(self):
        return self

    def next(self):
        if self.n < self.max:
            r = self.b
            self.b = self.a + self.b
            self.a = r

            self.n = self.n + 1
            return r
        raise StopIteration()

yield 实现生成器。

def fab(max):
    n,a,b = 0,0,1
    while n < max:
        yield b
        a, b = b, a + b
        n += 1
        
f = fab(5)
print(f.next())
                    

总结

生成器实际是一个对象,可以利用计算换空间,内部有保存数据的空间和产生新数据的方法,每次调用产生新的数据。

yield 是类似 return 的关键字,返回一个生成器对象,再调用生成器对象,将从 yield 的下一条语句开始执行。