Lua可变参数 “attempt to index global ‘arg’ (a nil value)”

使用Lua可变参数在win包报错,在Unity上则完全没问题,win包用的Lua解释器是luajit,而Unity上用的Lua5.1.
其实是Lua在5.2及后续版本中去掉了arg全局关键字,导致在luajit版本中找不到arg而报错。

在 5.2 之前, Lua 将函数的可变参数存放在一个叫 arg 的表中, 除了参数以外, arg 表中还有一个域 n 表示参数的个数.
到了 5.2 中, 定义函数的时候, 如果使用了 "..." 表达式, 那么语言后台将不会再帮忙打包 "arg" 对象了, 它将直接使用 {...} 用可变参数中的所有值创建一个列表.

新的可变参数推荐用法:

function methodB(...)
      local arg = { ... } --Lua 5.2以后不再支持默认arg参数,{}与...之间要有空格
      print(arg[1], arg[2], arg[3]) -- 注意arg[]中间不能包含nil,需要特殊处理

      print(select(1, ...))
end

function methodA(...)
      methodB(...)
end

在一些比较老的lua文档手册上,lua5.2的可变参数用法还未更新,有点误人子弟。

复习下可变参数概念
The three dots (...) in the parameter list indicate that the function has a variable number of arguments. When this function is called, all its arguments are collected in a single table, which the function accesses as a hidden parameter named arg. Besides those arguments, the arg table has an extra field, n, with the actual number of arguments collected.

大致意思是:将多个不定数量的参数通过...封装在table中传递,当方法获取到这些参数时包含隐藏参数arg。

在处理arg打印输出时,注意nil值,常用的打印方式ipairs不支持数组下标不连续的情况,这种时候就需要引入select,调用select时,传入一个selector和变长参数,如果selector为数字n,那么select返回它的第n个可变实参,如果是字符串'#'则会返回变长参数总数。

local function args(...)
    if next({...}) then
        -- get the count of the params
        for i = 1, select('#', ...) do
            -- select the param
            local param = select(i, ...)
            print(param)
        end
    else
        print("empty var")
    end
end

args(10, nil, 30)

-- output:
-- 10
-- nil
-- 30

参考:
https://zhuec.gitbook.io/learning-notes/windows-da-jian-xia-lua-kai-fa-huan-jing/5.2+-lua-zhong-de-ke-bian-can-shu

posted @ 2020-05-07 14:22  bylle  阅读(4619)  评论(0编辑  收藏  举报