- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
协程、延续和生成器之间有什么区别?
最佳答案
我将从生成器开始,因为它们是最简单的情况。正如 @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
使用协程的一个例子是词法分析器和解析器。如果没有语言中的协程或以某种方式进行模拟,则需要将词法分析和解析代码混合在一起,即使它们实际上是两个独立的问题。但是使用协程,您可以分离词法分析和解析代码。
(我将讨论对称协程和非对称协程之间的区别。只要说它们是等价的,您可以从一种协程转换为另一种,而非对称协程——它们最像生成器—— - 更容易理解。我正在概述如何在 Python 中实现非对称协程。)
Continuation 实际上是非常简单的野兽。它们都是代表程序中另一个点的函数,如果您调用它,将导致执行自动切换到函数代表的点。您每天都在使用它们的非常有限的版本,甚至没有意识到。例如,异常可以被认为是一种由内而外的延续。我将为您提供一个基于 Python 的延续伪代码示例。
假设Python有一个名为callcc()
的函数,这个函数有两个参数,第一个是一个函数,第二个是调用它的参数列表。该函数的唯一限制是它采用的最后一个参数将是一个函数(这将是我们当前的延续)。
def foo(x, y, cc):
cc(max(x, y))
biggest = callcc(foo, [23, 42])
print biggest
会发生的情况是,callcc()
会依次使用当前延续 (cc
) 调用 foo()
,即对程序中调用 callcc()
的点的引用。当 foo()
调用当前延续时,它本质上与告诉 callcc()
返回调用当前延续的值相同,以及何时返回也就是说,它会将堆栈回滚到创建当前延续的位置,即当您调用 callcc()
时。
所有这一切的结果将是我们假设的 Python 变体将打印 '42'
。
关于python - 协程、延续、生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/715758/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!