协程、延续、生成器

2024-02-08

协程、延续和生成器有什么区别?


我将从生成器开始,因为它们是最简单的情况。正如 @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 中实现非对称协程。)

延续实际上是非常简单的野兽。它们都是代表程序中另一个点的函数,如果您调用它,将导致执行自动切换到函数代表的点。您每天都在使用它们的非常有限的版本,甚至没有意识到。例如,异常可以被认为是一种由内而外的延续。我将为您提供一个基于 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()返回您调用当前延续的值,当它这样做时,它会将堆栈回滚到创建当前延续的位置,即当您调用时callcc().

所有这一切的结果是我们假设的 Python 变体将打印'42'.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

协程、延续、生成器 的相关文章

随机推荐

  • 切换到 Xcode 8.2.1 会导致 BRCloudDocsErrorDomain

    当我从 Xcode 7 3 1 切换到 Xcode 8 2 1 时 当我第一次尝试保存 通过 Cmd s 时 出现以下错误 错误 无法获取 URL 的容器 file Users bob Desktop 错误 错误域 BRCloudDocsE
  • Graphene Django - 一对多关系外键的突变

    我想知道如何正确创建突变来创建这个 django 模型 class Company models Model class Meta db table companies app label core default permissions
  • 获取谷歌地图中的当前位置并将其传递给javascript中的变量

    我想在谷歌地图中显示从当前位置到已知位置的方向 我的代码如下所示
  • 您可以冻结 C/C++ 进程并在不同的主机上继续它吗?

    我想知道是否可以生成一个 核心 文件 将其复制到另一台机器 然后继续在那台机器上执行核心文件 我见过 gcore 实用程序 它可以从正在运行的进程中生成核心文件 但我不认为gdb可以基于核心文件继续执行 有没有什么方法可以转储堆 堆栈并在以
  • TFS 构建自动化

    我有 TFS 2010 构建一个项目解决方案 它是一个复印机 构建成功但什么也没做 即 不复制 我如何让触发的构建来复制文件 Thanks 我有 TFS 2010 和 VS professional 2010 EDIT Update 复印机
  • 无法从 Servlet 过滤器内的 FacesContext 检索会话

    对我的用户进行身份验证后 我想在会话中添加对当前登录用户的引用 这是我如何做到的setCurrentUser方法 FacesContext facesContext FacesContext getCurrentInstance HttpS
  • Google oauth2client 出现 EOF 错误(Python、google-app-engine)

    我目前在我的 Python Web 应用程序中使用 oauth2client 以便使用 Google 的日历 API 我将 oauth2client 复制到目录的根文件夹中 然后按照以下说明进行操作https developers goog
  • 如何使用 SendKeys 将模拟键盘敲击发送到活动窗口

    我是 Python 新手 正在尝试将击键组合发送到我在 Windows 7 下打开的应用程序 虽然当我出于测试目的调用 Notepad exe 时 我的脚本可以完美运行 但它不适用于我正在尝试的实际应用程序使用 到目前为止 这是我的代码 i
  • 是否可以在容器组件的函数之间传递 React 组件作为参数

    将子组件作为参数传递给父组件的函数并尝试渲染不起作用 React Container Component Import Both Views and Render based on preference import PosterView
  • Windows Chrome 扩展本机消息传递只能接收第一个响应

    我正在尝试使用本机消息传递将一些数据发送到我的本机 Windows 应用程序 它与runtime sendNativeMessage 方法配合得很好 当我尝试使用使用端口的长期连接时 它也可以将数据从 Chrome 传递到我的应用程序 但是
  • 使用包含 $$ 字符的 SQLExec 执行文件

    我使用 pg dump 创建了一个 sql 转储文件 此导出文件包含包含 字符的函数 使用 psql f 导入文件没有问题 如果想使用 SQLExec 任务通过 ant 导入文件 我会得到如下异常 org postgresql util P
  • 来自上传文件的数据

    我有一个代码 其中包含上传到文件夹的文件数量 我希望将这些文件的名称 大小和 URL 存入数据库 但我的控制器无法正常工作 我使用 CakePHP 框架 我想将这些文件数据添加到数据库中 所有文件数据 但出现错误 Error Notice
  • 如何识别显示为空括号的空 NSData 对象?

    我正在处理 Game Kit 的 GKTurnBasedMatch 类中的损坏问题 请参阅这个线程 https stackoverflow com questions 15373903 removing a gkturnbasedmatch
  • 将结构插入映射时如何使用结构的成员作为其自己的键而不重复它?

    是否可以将结构插入到映射中 其中键由所插入的值拥有 当在 C 中使用哈希映射时 这是我习惯做的事情 伪代码示例 struct MyStruct pub map BTreeMap lt String StructThatContainsStr
  • 问:更改 Android Studio 中的通知图标

    我配置了应用程序图标 图 1 但通知图标 通过 Firebase 发送的通知 显示灰色矩形 图 2 通过 Android Studio 2 3 或通过脚本更改通知图标图像 图 2 的过程是什么 Manifest
  • Rails3 中的行为树?

    我需要在我的 Rails3 项目 ruby 1 9 2 中使用 Acts As Tree 但是 github上有很多fork 所以我不知道我应该选择哪个 哪个被其他开发者使用 在 Railsplugins org 上有http www ra
  • 使用 ViewBag 中的列表选择 TagHelper

    我目前正在尝试在 asp net 5 中使用 taghelpers 我想使用带有 ViewBag 列表的选择标签助手 我放入 asp for 字段的任何内容都会出错 因为它试图从 IEnumerable 模型而不是视图包中提取它 我想替换这
  • 如何过滤此 PHP 数组对象中的唯一对象[重复]

    这个问题在这里已经有答案了 我有一个从服务器端生成的对象数组 我想在 PHP 中过滤重复项 下面是生成的数组 array 5 0 gt 204 category name Fashion category id fashion 1 gt 2
  • Android如何通过xml或编程绘制正多边形

    有没有办法在 Android xml 布局上绘制多边形形状 或者是否有任何辅助类作为库来绘制它们 我正在使用增强版这个班 https gist github com AnderWeb face86a92e28fe32983a 请参阅工作示例
  • 协程、延续、生成器

    协程 延续和生成器有什么区别 我将从生成器开始 因为它们是最简单的情况 正如 zvolkov 提到的 它们是可以重复调用而不返回的函数 对象 但在调用时将返回 产生 一个值 然后挂起它们的执行 当他们再次被调用时 他们将从上次暂停执行的地方