协同程序中的返回值
可以写在coroutine.yield(返回值,返回值.....) ,也可以直接return 返回值,返回值.....
coroutine.yield和coroutine.resume都是可以拥有多个返回值的!
coroutine.resume的第一个返回值用来表示协程是否执行成功;从第二个开始往后的返回值是coroutine.yield所返回的。
coroutine.yield的返回值是由coroutine.resume传入的,即coroutine.resume的参数(除了第一个参数以外的)。
关于协同程序内部和外部(主程序)的数据交流
下面是一段菜鸟教程的代码以及执行结果:
1 function foo (a) 2 print("foo 函数输出", a) 3 return coroutine.yield(2 * a) -- 返回 2*a 的值 4 end 5 6 co = coroutine.create(function (a , b) 7 print("第一次协同程序执行输出", a, b) -- co-body 1 10 8 local r = foo(a + 1) 9 10 print("第二次协同程序执行输出", r) 11 local r, s = coroutine.yield(a + b, a - b) -- a,b的值为第一次调用协同程序时传入 12 13 print("第三次协同程序执行输出", r, s) 14 return b, "结束协同程序" -- b的值为第二次调用协同程序时传入 15 end) 16 17 print("main", coroutine.resume(co, 1, 10)) -- true, 4 18 print("--分割线----") 19 print("main", coroutine.resume(co, "r")) -- true 11 -9 20 print("---分割线---") 21 print("main", coroutine.resume(co, "x", "y")) -- true 10 end 22 print("---分割线---") 23 print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine 24 print("---分割线---") 25 26 执行结果: 27 第一次协同程序执行输出 1 10 28 foo 函数输出 2 29 main true 4 30 --分割线---- 31 第二次协同程序执行输出 r 32 main true 11 -9 33 ---分割线--- 34 第三次协同程序执行输出 x y 35 main true 10 结束协同程序 36 ---分割线--- 37 main false cannot resume dead coroutine 38 ---分割线---
对第10行的输出结果是 “第二次协同程序执行输出 r ”,感到了疑惑:
r不是在第8行的时候,赋值为 coroutine.yield(2 * a) 了吗? 而coroutine.yield(2 * a)的返回值是 4 才对,输出结果应该是 “第二次协同程序执行输出 4 ”。
琢磨之后,明白了这是为什么:
在第3行的 return coroutine.yield(2 * a) 所返回的值,没有赋值到 r 中;而是直接跳出了当前协程,返回到了第17行的 coroutine.resume 处,被print了出来。
程序继续往下走,从第19行开始,coroutine.resume传入了 “r”:
进入协程,执行到第3行,第3行的return coroutine.yield(2 * a) ,此时才真正的返回了值,返回的值正是传入的“r” 。
foo函数结束,local r 的值为foo函数的返回值 “r” 。
菜鸟教程上的一句话:
resume和yield的配合强大之处在于,resume处于主程中,它将外部状态(数据)传入到协同程序内部;而yield则将内部的状态(数据)返回到主程中。
我自己的总结:
在协程内部执行yield时,会返回传入参数到外部的resume中,作为resume返回值的一部分(从第二个返回值开始)。
外部的resume执行时,会把从第二个开始的参数传入到协程内部的yield中,作为yield的返回值。
待补充...
请发表评论