Lua可变参数函数
基础规则
lua传入参数给一个function时采用的是“多余部分被忽略,缺少部分有nil补足”的形式:
function f(a, b)
return a or b
end
CALL PARAMETERS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4 (5 is discarded)
unpack/pack
table.unpack和table.pack分别是数组的拆装处理,unpack函数输入数组,返回数组的所有元素:
tb = {1,2,3}
a,b,c = table.unpack(tb)
print(a) --1
print(b) --2
print(c) --3
pack函数输入多值,返回由这些值组成的数组:
a = table.pack(1,2,3)
print(a) --table: 000002687821C910
print(a.n) --3
table.pack(...)就是在外面包一层{},即{ ... }.
实际上table.unpack()函数可以通过以下lua代码来实现:
function unpack(tb,i)
i = i or 1
if tb[i] then
return tb[i],unpack(tb,i+1)
end
end
为什么提到unpack函数,是后面需要配合另一个机制使用。
...和arg的应用
在函数参数列表中使用三点(...)表示函数有可变的参数,print实际上就是用了这点来无限拼接字符串:
function printMySelf( ... )
local strResult = ""
for i,v in ipairs(table.pack(...)) do
strResult = strResult..v
end
print(strResult)
end
printMySelf(1,"a","b",2) --1ab2
在lua5.1版本之前,可以在函数中使用arg来定位可变参数,在函数内部arg就等于table.pack(...),即如下:
function select(n, ...)
return arg[n]
end
print(string.find("hello hello", " hel")) --> 6 9
print(select(1, string.find("hello hello", " hel"))) --> 6
print(select(2, string.find("hello hello", " hel"))) --> 9
但是5.1版本之后这上面的select函数会因为去掉了arg全局关键字而报空:
print(select(1, string.find("hello hello", " hel"))) --> nil
print(select(2, string.find("hello hello", " hel"))) --> nil
所以后续版本需要显式强调arg才行:local arg = { ... }
由此我们可以传入一个table.unpack的数组,然后用...机制操作参数即可:
function printMySelf( ... )
local strResult = ""
for i,v in ipairs(table.pack(...)) do
strResult = strResult..v
end
print(strResult)
end
local tbNeedPrint = {"hello!","world"}
printMySelf(table.unpack(tbNeedPrint)) --hello!world