在lua中,
问题1:如果你在可变参数...中传入若干个参数,其中有的参数要带nil,这时怎么解决呢?(比如local function _test(...) end _test(1, nil, 3))
问题2:更甚于在一个带可变参数的函数里返回值是一个带可变参数的尾调用,这时还能正确得到要的参数?(比如 local function _test2(...) return function(...) end end _test2(4, nil, 6))
接下来几行大致过下基础知识:
lua中nil是代表无(这不是废话吗?别急,往下看):
--比如: local a = 10 a = nil print(a) --这时输出的a是nil --再比如: local a = {1, nil, 3, 4} for k, v in pairs(a) do print(k, '=', tostring(v)) end --这时输出的是 1 = 1 3 = 3 4 = 4 --也就是跳过了第二个为nil的键值对
先来解决问题1,看这个例子:
local function _test(...) local paramCount = select('#', ...) local printStr = '' for i = 1, paramCount do local v = select(i, ...) printStr = printStr..i..'='..tostring(v)..', ' end print(printStr) end _test(1, nil, 2, 3) --输出为: 1=1, 2=nil, 3=2, 4=3
上面可以看到正确地拿到了nil参数,它确实是在第2位的;主要就是利用select函数取到可变参数的总个数,如果你是要在_test(...)函数中将可变参数保存下来,然后在适当的时机再传到其他的函数中,则需要按下面这种方式:
local paramT local function _test(...) paramT = {paramCount=select('#', ...), ...} end local function _receiveArg(...) local paramCount = select('#', ...) local printStr = '' for i = 1, paramCount do local v = select(i, ...) printStr = printStr..i..'='..tostring(v)..', ' end print(printStr) end _test(1, nil, 2, 3) _receiveArg(unpack(paramT, 1, paramT.paramCount)) --同样地输出: 1=1, 2=nil, 3=2, 4=3,
主要就是使用unpack函数,把参数表paramT解包作为参数传过去,但要注意指定参数对应的索引范围是1~paramT.paramCount,特别的paramT.paramCount这个是存放在table中的hash部分,所以不受影响;
最后解决问题2,看这个例子:
local function _receiveArg(...) local paramCount = select('#', ...) local printStr = '' for i = 1, paramCount do local v = select(i, ...) printStr = printStr..i..'='..tostring(v)..', ' end print(printStr) end local function _test2(func, ...) local paramT = {...} local paramCount = select('#', ...) return function(...) local callbackParamCount = select('#', ...) for i = 1, callbackParamCount do paramT[paramCount + i] = select(i, ...) end return func(unpack(paramT, 1, paramCount + callbackParamCount)) end end local func = _test2(_receiveArg, 10, nil, 30) func(nil, 40, nil, 50) --输出:1=10, 2=nil, 3=30, 4=nil, 5=40, 6=nil, 7=50,
主要看_test2(func, ...)这个函数里中的function(...)尾调用的处理!里面是合并了_test2函数的可变参数列表与这个尾调用的可变参数列表!并最后顺序把参数原封不动地return。
大致就这些,题外话:现在在我们的游戏里使用lua就上面这样的写法,原先想用coroutine替换掉这些回调(尾调用),因为之前就是碰到可变参数里带nil值的情况无法正确的处理!(用谷歌搜索了一些博文,但都没提到我想要的解决方案)最后还是在stackoverflow(见这个网址:http://stackoverflow.com/questions/7183998/in-lua-what-is-the-right-way-to-handle-varargs-which-contains-nil)看了unpack的正确用法(得到了启发),归根结底还是没先去看官方文档中select与unpack函数的正确用法导致!!所以上述的是实现方式是我花了一点时间相(想)通后实现的!