我发现重用曾经创建的 coroutine
真的很有用.我找到了一个解决方案,它看起来像这样:
co = coroutine.create(function (f, args)
while f do
f = coroutine.yield(f(args))
end
end)
function dummyFunc(data)
print("XXX "..data)
coroutine.yield()
print("OOO "..data)
end
coroutine.resume(co, dummyFunc, "1")
coroutine.resume(co, dummyFunc, "2")
coroutine.resume(co, dummyFunc, "3")
coroutine.resume(co, dummyFunc, "4")
除了输出是 不是 :
XXX 1
OOO 2
XXX 3
OOO 4
这是:
XXX 1
OOO 1
XXX 1
OOO 1
那么是否可以将参数更改为
dummyFunc
在简历电话之间?
最佳答案
想想这个。协程的工作方式是这样的。当你第一次resume
他们,你传递给 resume
的参数成为协程函数的参数。当协程yield
s,它传递给 yield
的参数成为您 resume
的返回值称呼。
但是,第二次你resume
协程,它不会进入仍在执行的函数中并更改第一次传入的参数。改变函数局部变量的值是非常粗鲁的。
因此,对 resume
的参数第一次调用后的调用将是来自 yield
的返回值.
co = coroutine.create(function (f, args)
while f do
f = coroutine.yield(f(args))
end
end)
所以你需要这样做:
co = coroutine.create(function (f, args)
while f do
f, args = coroutine.yield(f(args))
end
end)
但是,如果你想要更灵活的东西,可以做可变数量的参数,你需要更聪明:
co = coroutine.create(function (...)
local function capture_args(...)
return {...}, select("#", ...)
end
local tbl, len = capture_args(...)
local f = tbl[1]
while f do
tbl, len = capture_args(coroutine.yield(f(unpack(tbl, 2, len))
f = tbl[1]
end
end)
有些人不会理会
capture_args
东西,只靠{...}
并调用 unpack
在上面。这样更安全,因为用户可以把 nil
参数列表中的值。 ...
将记录所有参数,甚至嵌入 nil
s(但不是尾随)。但是,一旦放入数组中,数组的长度是基于第一个nil
值(value)。使用
capture_args
,由于select
的一个鲜为人知的特性,您可以获得实际的参数计数。 .并感谢unpack
的能力要在给定的范围上工作,即使范围超过表的长度,也可以有效地存储参数列表。我可能会做
capture_args
通过将长度放在它返回的表中来更聪明。但这对我来说已经足够了。这里还有第二个问题:你在
dummyFunc
内让步, 和 dummyFunc
似乎不明白如何处理 yield
的返回值(即:下一次 resume
调用的参数)。不清楚您想要什么
dummyFunc
回应它。如果您需要 dummyFunc
的参数更改,因为您如何在没有 dummyFunc
的情况下恢复它知道这一点,这不会发生。
关于function - 在lua中每次调用重用具有不同参数的协程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32627495/