义齿
協程についてまだ深く認識していないので、いくつか例を貼っておきましょう.
luaが記述したコヒーレンス例:yieldのパラメータはresumeによって返され、resumeのパラメータはyieldによって返される.
wrapで作成されたcoroutineは、呼び出し時にresume機能と似ています.渡されたパラメータはyieldの戻り値として、yield文が実行されるとwrap関数の戻り値が生成されます.
実行結果を添付:
luaが記述したコヒーレンス例:yieldのパラメータはresumeによって返され、resumeのパラメータはyieldによって返される.
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))
出力結果:co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine
第2例coro = {}
coro.main = function() end
coro.current = coro.main
function coro.create(f)
return coroutine.wrap(function(val)
return nil,f(val)
end)
end
function coro.transfer(k,val)
if coro.current ~= coro.main then
return coroutine.yield(k,val)
else
while k do
coro.current = k
if k == coro.main then
return val
end
k,val = k(val)
end
error("coroutine ended without transfering control...")
end
end
function foo1(n)
print("1: foo1 received value "..n)
n = coro.transfer(foo2,n + 10)
print("2: foo1 received value "..n)
n = coro.transfer(coro.main,n + 10)
print("3: foo1 received value "..n)
coro.transfer(coro.main,n + 10)
end
function foo2(n)
print("1: foo2 received value "..n)
n = coro.transfer(coro.main,n + 10)
print("2: foo2 received value "..n)
coro.transfer(foo1,n + 10)
end
function main()
foo1 = coro.create(foo1)
foo2 = coro.create(foo2)
local n = coro.transfer(foo1,0)
print("1: main received value "..n)
n = coro.transfer(foo2,n + 10)
print("2: main received value "..n)
n = coro.transfer(foo1,n + 10)
print("3: main received value "..n)
end
coro.main = main
coro.current = coro.main
coro.main()
coroutineについて.wrap、ヘルプドキュメントには次のセクションがあります.wrapで作成されたcoroutineは、呼び出し時にresume機能と似ています.渡されたパラメータはyieldの戻り値として、yield文が実行されるとwrap関数の戻り値が生成されます.
Like coroutine.create, the coroutine.wrap function also creates a coroutine, but instead of returning the coroutine itself,
it returns a function that, when called, resumes the coroutine. Any arguments passed to this function go as extra arguments
to coroutine.resume. coroutine.wrap returns all the values returned by coroutine.resume, except the first one (the boolean
error code). Unlike coroutine.resume, coroutine.wrap does not catch errors; any error is propagated to the caller.
実行結果を添付:
1: foo1 received value 0
1: foo2 received value 10
1: main received value 20
2: foo2 received value 30
2: foo1 received value 40
2: main received value 50
3: foo1 received value 60
3: main received value 70