[lua] 你所不知道的lua nil值在可变参数函数中怎么处理!

在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函数的正确用法导致!!所以上述的是实现方式是我花了一点时间(想)通后实现的!

转载于:https://www.cnblogs.com/AlphaAI/p/6550383.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值