Function 在lua中使用每个调用的不同参数重用协同路由
我发现重用曾经创建的Function 在lua中使用每个调用的不同参数重用协同路由,function,lua,arguments,coroutine,Function,Lua,Arguments,Coroutine,我发现重用曾经创建的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.res
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
的参数将是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
值
使用capture\u args
,由于select
的一个鲜为人知的功能,您可以获得实际的参数计数。由于unpack
能够在给定的范围内工作,即使范围超过了表的长度,您也可以有效地存储参数列表
通过将长度放入它返回的表中,我可能会使capture_args
更聪明一些。但这对我来说已经足够好了
这里还有第二个问题:您在
dummyFunc
中让步,而dummyFunc
似乎不明白如何处理yield
的返回值(即:下一次恢复
调用的参数)
尚不清楚您希望如何
dummyFunc
响应它。如果您想更改dummyFunc
的参数,因为您在不知道dummyFunc
的情况下恢复了它,那是不会发生的。您看过本手册的章节了吗?它显示了一个非常类似的例子。我想这不是我想要的。corroutine中的函数“内部”更改值(本质类型)。就我对代码的理解而言,通过给出的变量并没有真正改变,而是产生了(某种外在的)。我可能是错的,但是,如果是这样的话,为了清楚起见,您能否发布一个简单的示例?您是否希望能够将数据
变量从外部更改为dummyFunc
,而无需通过coroutine.resume在中传递新值?您可能需要使用全局变量来实现这一点(假设偶数有效),这可能不是一个好主意/设计。不,我想(通过将值传递给resume
)而不使用全局变量来更改数据。这就是示例所做的。您有一个复杂的内部函数,不能捕获内部收益率
的结果,只能捕获一个恢复
传递的值。再看一遍例子。