这是一段分析 lua 协程(协同程序,coroutine)的代码,来自 Lua reference manual interface (略有修改):
复制代码 代码如下:
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body1", a, b)
local r = foo(a+1)
print("co-body2", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body3", r, s)
return b, "end"
end)
print("1----")
print("main", coroutine.resume(co, 1, 10))
print("2----")
print("main", coroutine.resume(co, "r"))
print("3----")
print("main", coroutine.resume(co, "x", "y"))
print("4----")
print("main", coroutine.resume(co, "x", "y"))
运行效果如下:
复制代码 代码如下:
1------
co-body1 1 10
foo 2
main true 4
2------
co-body2 r
main true 11 -9
3------
co-body3 x y
main true 10 end
4------
main false cannot resume dead coroutine
这里一共调用了 4 次 resume ,让我们来看看它是怎么运行的。
第一次:
复制代码 代码如下:
print("main", coroutine.resume(co, 1, 10))
1.执行 print("co-body1", a, b) ,a 和 b 的值为 resume 提供,a=1, b=10 ;
2.计算 a+1=2 ,进入 foo(a) ,同时将刚才的计算结果通过 a 参数传递,执行 print("foo", a);
3.考虑 return coroutine.yield(2*a) ;
4.计算 2*a=4 ,碰到 yield,挂起 foo(a) 调用,将 4 返回给 resume 。注意,foo 的 return 还没有执行;
5.resume 执行成功,返回 true, 4 。
第二次:
复制代码 代码如下:
print("main", coroutine.resume(co, "r"))
1.从上一次挂起的 foo(a) 调用开始执行,接着执行没有完成的 return 调用;
2.因为 yield 返回 resume 的调用参数,此时 foo(a+1) 返回的值就是字符串 "r"。这里比较难理解。
因为大家可能会顺理成章地认为 local r 这个变量的值应该是 yield(2*a) 中的 2*a 的值。
需要注意的是, yield 的返回值 与 yield 参数的值 是不同的。
前者你可以将其保存在一个变量中,或者 return 它,或者不使用它(不保存 yield 的返回结果);后者则是 resume 的返回值。
3.执行 print("co-body2", r) ,r 的值为 "r" ;
4.考虑 local r, s = coroutine.yield(a+b, a-b) ;
5.计算 a+b=11, a-b=-9 ,碰到 yield ,挂起 co 的调用,将 11 和 9 返回给 resume 。注意,此时 local r, s 的赋值还没有开始。
这里不太好理解的是,为什么 a 的值不是 "r" ?因为 "r" 已经被上面的 yield 的返回值给消费掉了。
6.resume 执行成功,返回 true, 11, -9 。
第三次:
复制代码 代码如下:
print("main", coroutine.resume(co, "x", "y"))
1.从上一次 yield 的地方开始执行,接着执行没有完成的 local r, s = 赋值。上面提到, yield 会返回 resume 的调用参数,因此 r 和 s 的值就是 "x" 和 "y" ;
2.执行 print("co-body3", r, s) 进行打印;
3.考虑 return b, "end" ;
4.b 的值一直都是 10 没有变,这里直接返回了,同时返回的还有 "end" 这个字符串;
5.由于协程函数返回的时候,它的所有返回值都作为 resume 的返回值返回。因此这里的 resume 执行成功,返回 10, "end" 。
第四次:
复制代码 代码如下:
print("main", coroutine.resume(co, "x", "y"))
由于 co 函数已经返回,它处于 dead 状态,不能 resume ,因此第 4 次 resume 失败。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 群星《赤热 电视剧音乐原声》[320K/MP3][427.21MB]
- 周华健.1996-爱的光【滚石】【WAV+CUE】
- 杨宗宪.1996-想啥人怨啥人等啥人【有容唱片】【WAV+CUE】
- 郑秀文.2024-Best.Concert.Live【华纳】【FLAC分轨】
- 《Pax Dei》配置要求一览
- 《过山车之心2》存档位置介绍
- 《三国志8 REMAKE》评测:自定义的三国演义
- 群星《少年白马醉春风 网剧OST原声专辑》[320K/MP3][117.05MB]
- 群星《少年白马醉春风 网剧OST原声专辑》[FLAC/分轨][621.04MB]
- 《魏佳艺5CD合集》[WAV分轨][3.8G]
- CSGO职业选手donk怎么样 2024最新donk个人资料介绍
- CSGO职业选手NiKo怎么样 2024最新Niko个人资料介绍
- 剑网3丝路风语PVE焚影怎么打 丝路风语PVE焚影圣诀手法配装攻略
- [老虎魚古典名盘]心碎SACD浪漫小提琴之声[DSF]
- Queen(皇后乐队)《GreatestHitsII》[SACD-DSF]