Lua的函数
在Lua中如果一个函数只有一个参数,并且此参数是一个字面字符串或table构造式,那么圆括号便是可有可无的。
例如:print "hello world" <----> print("hello world")
冒号操作符:表达式:o.foo(0,x) 可以写成是:o:foo(x)
5.1 多重返回值:
lua具有一项非常与众不同的特征,允许函数返回多个结果。
写一个函数用于查找数组中的最大元素,并返回该元素的位置
function maxinmum(a)
local mi=1 ---最大值的索引
local m=a[mi] --最大值
for i,val in ipairs(a) do
if val > m then
mi=i; m=val;
end
end
return m,mi
end
print(maximum({8,10,23,12,5})) --> 23 3
x,y,z=10,foo2() ---x=10,y=a,z=b
当函数出现在一个表达式中的时候,返回值数量调整为1
例如:print(foo2() .. "x") --->ax
table 构造是可以完整地接受一个函数调用的所有结果,即不会有任何数量方面的调整
t={foo2()} --->t={"a","b"}
不过,这种行为只有当一个函数调用作为最后一个元素时才会发生,而其他位置上的函数调用总是只产生一个结果值
t={foo0(),foo2(),foo3()} -->t[1]=nil,t[2]="a",t[3]=4
最后一种情况是return语句,诸如return f() 这样的语句将返回f的所有返回值
function foo(i)
if i==0 then return foo0()
elseif i==1 then return foo1()
elseif i==2 then return foo2()
end
end
print(foo(1))
关于多重返回值还要介绍一个特殊函数---unpack.他接受一个数组作为参数,并从下表1开始返回该数组的所有元素
print(unpak{10,20,30}) ---> 10 20 30
a,b=unpak{10,20,30} ---> a=10 ,b =20 ,30 被丢弃
unpack 的一项重要用途体现在“泛型调用(generic call)”机制中
例如:f=string.find
a={"hello","ll"}
if(unpack(a)) 将返回3和4,这与直接调用string.find("hello","ll") 所返回的结果一模一样。
虽然,这个预定义函数unpack是用C语言编写的,但是仍然可以在Lua中通过递归实现一样效果:
function unpack(t,i)
i=i or 1
if t[i] then
return t[i] , unpack(t , i+1)
end
end
第一次调用时传入一个是参数,此时i=1,然后,函数返回t[1] 与 unpack(t,2)调用的结果,后者又将返回t[2] 与 unpack(t,3) 的结果,一次类推。直至遇到第一个nil元素停止递归。
5.2 变长参数
lua中的函数可以接受不同数量的实参。例如,在调用print时可以传入一个,二个或者多个实参。虽然print使用c语言编写的,但也可以用lua编写出这种能接受不同数量实参的函数。
下面是一个简单的例子,这个函数返回了所有参数的总和:
function add(...)
local s = 0
for i,v in ipairs{...} do
s=s+v
end
return s
end
print(add(3,4,10,25,12)) --->54
参数中3个点(...) 表示该函数可接受不同数量的参数。当这个函数被调用时,他的所有参数都会被收集到一起。这部分收集起来的实参成为这个函数的“变长参数” 。一个函数要访问它的变长参数时,仍需用到3个点(...).但不同的是,此时这3个点是作为一个表达式来使用的。在上例中,表达式{...}表示一个有所有变长参数构成的数组。而函数add遍历了该数组,并累加了每个元素。
表达式“...”的行为类似于一个具有多重返回之的函数,它返回的是当前函数的所有变长参数。例如:
local a,b=...
上例用第一个和第二个变长参数来初始化这两个局部变量。实际上,还可以通过变长参数来模拟Lua中普通的参数传递机制,例如:
function foo(a,b,c)
可以转换为:
function foo(...)
local a,b,c =...
end
下面示例演示了,如何使用select来遍历一个函数的所有变长参数:
for i=1,select ('#',...) do
local arg=select(i, ... ) ---得到第i个参数
《循环体》
end
需要特别指出,select(“#”, ... ) 会返回所有变长参数的总和,其中包括nil