Lua 中一对resume-yield 可以相互交换数据。
co = coroutine.create(function () for i = 1, 3 do print("LUA") coroutine.yield() end end) for i = 1, 5 do coroutine.resume(co) end >lua -e "io.stdout:setvbuf 'no'" "test.lua" LUA LUA LUA >Exit code: 0
resume 返回除了true 以外的其他部分将作为参数传递给相应的yield
co = coroutine.create(function (a,b) coroutine.yield(a + b, a - b) end ) print(coroutine.resume(co, 20, 10)) --> true 30 10 >lua -e "io.stdout:setvbuf 'no'" "test.lua" true 30 10 >Exit code: 0
yield 返回值与resume传入的值对应 (假设上面那条成立,这个特性也就显而易见了)
co = coroutine.create ( function () print("then yield", coroutine.status(co)) print(coroutine.yield()) end ) print("when create", coroutine.status(co)) print("----------------------------") coroutine.resume(co, "1st resume") print("after yield", coroutine.status(co)) print("----------------------------") coroutine.resume(co, "2nd resume") print("after resume", coroutine.status(co)) >lua -e "io.stdout:setvbuf 'no'" "test.lua" when create suspended ---------------------------- then yield running after yield suspended ---------------------------- 2nd resume after resume dead >Exit code: 0
对比上面两个执行结果还可以看出协同的生命周期:协同从create诞生,然后挂起,在resume中唤醒,由yield运行后再挂起,挂起时如果再次唤醒而没有yield则直接终结之。
yield有生产的意思,生命周期有如下规律: 诞生->挂起->唤醒(yield)->挂起->唤醒(no yield)->终结。
协同代码结束时主函数返回的值都会传给相应的resume
co = coroutine.create(function () return 6, 7 end ) print(coroutine.resume(co)) --> true 6 7