协程与持续vs发电机

协程和延续与发生器有什么区别?

我会从发电机开始,看他们是最简单的情况。 正如@zvolkov所提到的,它们是可以在不返回的情况下重复调用的函数/对象,但是当被调用时会返回(产生)一个值,然后暂停执行。 当他们再次被调用时,他们将从他们上次暂停执行的地方启动,并再次执行他们的事情。

发生器本质上是一个削减(不对称)协程。 协程和发生器之间的区别在于,协程在初始调用之后可以接受参数,而发生器不能。

用一个简单的例子来说明你使用协程的过程有点困难,但这是我最好的尝试。 以此(构成)Python代码为例。

def my_coroutine_body(*args): while True: # Do some funky stuff *args = yield value_im_returning # Do some more funky stuff my_coro = make_coroutine(my_coroutine_body) x = 0 while True: # The coroutine does some funky stuff to x, and returns a new value. x = my_coro(x) print x 

使用协程的例子是词法分析器和parsing器。 如果没有语言中的协程或者不知何故模拟,即使它们真的是两个不同的问题,也需要混合在一起。 但是使用协程,你可以分离出lexing和parsing代码。

(我将会研究对称和不对称协程之间的区别,只要说它们是等价的,就可以从一个转换到另一个,而非对称协程(最类似于发生器)是更容易理解,我正在概述如何在Python中实现非对称协程)。

延续是非常简单的野兽。 它们都是代表程序中另一个点的函数,如果你调用它,会导致执行自动切换到函数表示的点。 你甚至没有意识到它们每天都使用非常有限的版本。 例如,例外可以被认为是一种内外延续。 我会给你一个基于Python的延续伪代码的例子。

说Python有一个叫做callcc()的函数,这个函数有两个参数,第一个是一个函数,第二个是调用它的参数列表。 对这个函数的唯一限制就是最后一个参数是一个函数(这将是我们目前的延续)。

 def foo(x, y, cc): cc(max(x, y)) biggest = callcc(foo, [23, 42]) print biggest 

会发生什么情况是callcc()会依次调用foo()和当前的继续( cc ),即引用callcc()被调用的程序中的一个点。 当foo()调用当前延续时,它基本上与告诉callcc()返回当前延续的值一样,当它返回时,它将堆栈回滚到当前延续创build的位置即,当你调用callcc()

所有这一切的结果是,我们假设的Python变体将打印“42”。

我希望有所帮助,而且我相信我的解释可以在很大程度上得到改善!

协程是几个轮stream工作的程序之一,然后停下来控制组中的其他协程。

Continuation是一个“指向一个函数的指针”,你传递给某个过程,在该过程完成时被执行(“继续”)。

生成器(.NET)是一种语言结构,可以吐出一个值,“暂停”执行该方法,然后在询问下一个值时从同一点开始。

在较新版本的Python中,可以使用generator.send()将值发送给发生器,这使得Python发生器能够有效地进行协同处理。

python发生器,和其他发电机,如greenlet,之间的主要区别是,在Python中,您的yield value只能返回给调用者。 在greenlet中, target.switch(value)可以带你到一个特定的目标协程并产生一个target将继续运行的值。