• 请不要在回答技术问题时复制粘贴 AI 生成的内容
zjsxwc
V2EX  ›  程序员

yield 明明是用来做生成器 generator 的, 为什么好多人要用来做"协程"?

  •  
  •   zjsxwc ·
    zjsxwc · Oct 14, 2017 · 4496 views
    This topic created in 3310 days ago, the information mentioned may be changed or developed.

    yield 本意作为 generator 是很方便的,但好多人要用来做"协程"...

    这种 yield 做"协程"的方式,让我想到了当年 C 里的 goto 语句, 把代码写到很混乱, 明明是种反模式, 却会被人追捧.

    你们怎么看?

    17 replies  •  2017-10-15 16:11:24 +08:00
    sunjourney
    sunjourney
    Oct 14, 2017
    1
    这取决于你怎么 yield,你既可以 yield 符合调度器协议的东西,也可以不,但你总归需要去调试它,要么自动(携协),要么手动。
    sunjourney
    sunjourney
    Oct 14, 2017
    2
    携协 -> 协程

    手快了
    kindjeff
    kindjeff
    Oct 14, 2017 via iPhone
    3
    啥叫好多人,官方不都这么做了么。
    GeruzoniAnsasu
    GeruzoniAnsasu
    Oct 14, 2017
    4
    不是 yield 用来做协程
    首先你要明白协程解决了什么问题
    在异步模式下,传统的解决方式是用各种回调来处理异步 IO 的结果,当 IO 完成时产生事件并由回调去处理事件
    然而这样的模式 io 发起代码和回调无法写在一起,当异步操作多了之后回调大量增加代码可读性会急剧下降
    而采用协程的模式,发起请求和回调处理写在一起就像一个普通的 block 线程一样
    发起 io 时 yield 出当前函数,当请求完成后由调度器调度回本函数继续在 yield 的位置往下执行,结构就简单清晰很多
    并不是 yield 做协程,而是协程模式必须要有 yield 才可能实现
    hjc4869
    hjc4869
    Oct 14, 2017
    5
    问题是 coroutine 代码一点都不混乱,可读性比别的写法强啊(
    hjc4869
    hjc4869
    Oct 14, 2017
    6
    coroutine 做得好的比如 C#,你把 async await 关键字和方法签名里的 Async 后缀忽略掉,就跟同步阻塞的程序没有什么区别了。
    beginor
    beginor
    Oct 14, 2017 via Android
    7
    @hjc4869 async 和 await 最早出现在 F#中,巨硬觉得这个比较屌,可以甩 Java 多少年,可是 F#始终是少数派中的少数派,最终移值到了 C#
    NoAnyLove
    NoAnyLove
    Oct 14, 2017
    8
    那是因为 Guido 对于添加关键字过于谨慎了,不过在后来的版本中还是加入了 async 和 await 关键字。另外,Python 的 coroutine 就是在 generator 之上发展出来的,事实上在官方支持 coroutine 之前,第三方的库就基于 generator 实现了 coroutine,所以也可以说是历史遗留问题。

    最后,yield 的语法用于 coroutine 并没有觉得凌乱,虽然有可能让人不能一下区分一个函数到底是 coroutine 还是 generator ;另外,goto 虽然被认为是经典的反例,但其实是被过度宣传了,在适合它的场景中,goto 是非常好用的。
    hcnhcn012
    hcnhcn012
    Oct 14, 2017 via iPhone
    9
    。。。完成协程还有比 yield 更 python 的特性么?
    geelaw
    geelaw
    Oct 14, 2017 via iPhone❤️1
    10
    呃……迭代器不是 coroutine 的一个例子么?

    我更感兴趣为什么要造出 coroutine 这个名词,因为从形式上来说 subroutine 更简单,并且 coroutine 就是保存了调用栈的、多次运行第一步是跳转到上次结束位置之后的一段构造。或许对于 programming 的 philosophy 是有好处的吧。
    jiangzhuo
    jiangzhuo
    Oct 14, 2017
    11
    这事你得问 tj
    ipwx
    ipwx
    Oct 14, 2017
    12
    你可以选择 Python 3.5+,有 async await 替代历史遗留的 @coroutine 和 yield from。

    当然,内部实现还是差不多的。
    QAPTEAWH
    QAPTEAWH
    Oct 14, 2017 via iPhone
    13
    背后的原理是一样的( continuation )
    gouchaoer
    gouchaoer
    Oct 14, 2017 via Android
    14
    写起来很麻烦,还是全协程好用
    chengluyu
    chengluyu
    Oct 15, 2017
    15
    协程怎么和 goto 划等号的……
    ivechan
    ivechan
    Oct 15, 2017
    16
    "The yield expression is used when defining a generator function or an asynchronous generator"
    "A Python generator is a form of coroutine,"
    说白了 generator 其实也是一种 coroutine。
    sexrobot
    sexrobot
    Oct 15, 2017
    17
    http://www.laruence.com/2015/05/28/3038.html
    yield 的造物主都这么用了.
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4782 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 62ms · UTC 08:14 · PVG 16:14 · LAX 00:14 · JFK 03:14
    ♥ Do have faith in what you're doing.