函数
函数的简单定义:
function add( a,b )
local c=a+b
print(c)
return c
end
print(add(1,2))
--输出
3
3
函数调用时:当函数只有一个参数且该参数是字符串常量或表构造器时,括号可选
print "abc" -- 等价于 print("abc")
print {1,2,3} -- 等价于 print({1,2,3})
--输出
abc
table: 001b8518
函数参数个数不一致时:此时会抛弃多余参数和不足的参数设置为nil
function f( a,b,c )
print(a,b,c)
end
f(1)
f(1,2)
f(1,2,3)
f(1,2,3,4)
--输出
1 nil nil
1 2 nil
1 2 3
1 2 3
默认参数的情况:当参数不够时,可以实现默认参数
c=0
function count(n)
n=n or 1
c=c+n
end
count()
print(c)
--输出
1
多返回值
Lua允许函数返回多个值,一般使用多重赋值可以获取到所有结果。、
function f( a,b )
return b,a
end
a=1
b=2
print(a,b)
a,b=f(a,b)
print(a,b)
--输出
1 2
2 1
多返回值时根据函数的调用场景情况,调整返回值的数量。
- 当函数调用作为一条单独语句时,所有返回值都会被丢弃。
- 当函数调用被作为表达式(如,加法中的参数时),只返回第一个参数。
- 当作为一系列表达式的最后一个表达式时,所有的都可以返回到。
一系列表达式分为如下4种情况:
function f0( )
end
function f1( )
return 1
end
function f2( )
return 1,2
end
--1.多重赋值
---1.1函数调用放在最后则尽可能匹配更多的待赋值变量
print("......1.1.......")
x,y=f2()
print(x,y)
x=f2()
print(x)
x,y,z=0,f2()
print(x,y,z)
---1.2函数调用放在最后,若函数没有返回值或者返回值不够时使用nil填充
print("......1.2.......")
x,y=f0()
print(x,y)
x,y=f1()
print(x,y)
x,y,z=f2()
print(x,y,z)
---1.3函数调用放在最后,才能返回多个值,否则只返回一个
print("......1.3.......")
x,y=f2(),10
print(x,y)
x,y=f0(),20,30
print(x,y)
--2.函数调用
---2.1当函数调用是另外一个函数调用的最后一个参数时,所有返回值才会都作为实参
print("......2.1.......")
print(f2())
---2.2当函数调用不是另外一个函数调用的最后一个参数时,只返回一个值
print("......2.2.......")
print(f2(),3)
--3.表构造器
---3.1 当函数调用是最后一个表达式时,表会完整接受函数的所有返回值
print("......3.1.......")
a={f2()}
for i,v in ipairs(a) do
print(i,v)
end
---3.2 否则,只会返回一个结果
print("......3.2.......")
a={f1(),f2(),100}
for i,v in ipairs(a) do
print(i,v)
end
--4.return f()语句会返回f返回的所有结果。
print("......4.......")
function f( )
return f2()
end
print(f())
---将函数调用使用()括起来则可以强制其只返回一个结果。
-- 注意 return 语句后面的内容是不需要加括号的,否则会强制只返回一个结果
print((f2()))
--输出
......1.1.......
1 2
1
0 1 2
......1.2.......
nil nil
1 nil
1 2 nil
......1.3.......
1 10
nil 20
......2.1.......
1 2
......2.2.......
1 3
......3.1.......
1 1
2 2
......3.2.......
1 1
2 1
3 100
......4.......
1 2
1
可变长参数
用以支持任意长度的参数。
-- 居然还可以这样用
_ =2
print(_) --输出2
function add ( ... )
local s=0
for i,v in ipairs({...}) do
s=s+v
end
return s
end
print(add(1,2,3,4,5))
--输出
15
注:…称为可变长参数表达式,类似于一个具有多个返回值的函数。{…}用于构造这些参数的一个序列。
function f ( ... )
local a,b=...
print(a,b)
end
f(1,2,3,4,5)
--输出
1 2
要遍历可变长参数,函数可以使用表达式{…}将可变长参数放在一个表中。不过在罕见的情况下,如果可变长参数中包含了无效的nil,那么{…}中可能不在是一个序列。此时就没有办法在表中判断原始参数是否以nil结尾的。因此, ** Lua提供了table.pack ** (该函数使用表保存所有的参数,然后将其放在一个表中返回,并且该表还有一个保存了参数个数的额外字段“n”)
function nonils( ... )
local arg =table.pack(...)
print("\n")
for i=1,arg.n do
print(arg[i])
if arg[i] == nil then return false end
end
return true
end
print("-->",nonils(2,3,nil))
print("-->",nonils(2,nil,3))
print("-->",nonils(1,2,3))
--输出
2
3
nil
--> false
2
nil
--> false
1
2
3
--> true
另一种遍历函数的可变长参数的方法是使用函数select。
select (selector,…)
当selector为数值数值n时,则返回第n个参数后的所有参数;否则selector为“#”,则返回可变长参数参数的总数。
print(select(1,"A","B","C"))
print(select(2,"A","B","C"))
print(select(3,"A","B","C"))
print(select("#","A","B","C"))
--输出
A B C
B C
C
3
函数table.unpack
其与table.pack相反,pack将参数列表转换为一个真实的表,而unpack则将一个表返回成一组返回值,进而可以作为另一个函数的参数使用。
print(table.unpack{1,2,3})
print(table.unpack{1,nil,3})
--输出
1 2 3
1 nil 3
由于函数table.unpack使用长度操作符获取返回值的个数,因而只能用于序列。另外,还可以限制反悔元素的范围。
print(table.unpack({1,2,3,4,5,6,7,8,9},2,7))
--输出
2 3 4 5 6 7
Lua实现了尾递归优化
原理可参考–>谈一谈尾调用优化