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