函数基础
(1)函数
格式:
function fun_name(params)
--body
end
调用方式:
o.fun(x) 或 o:fun(x)
其中冒号调用方式会隐含将o作为函数第一个参数传入;
参数:形参和实参数量可以不同,规则和多重赋值一致;
多重返回值:只需在return时这样写
return a, b, c
print可以接受不同数量的实参,多重返回值的函数可以直接作为其它函数的参数,也可以作为table的构造式 –> a = {f()};
(2)table.unpack
返回数组中所有值
print(table.unpack({10, 20, 30}))
local a = {10, 20, 30}
print(table.unpack(a))
local a = {}
a[1] = 10;
a[2] = 20;
a[3] = 30;
print(table.unpack(a))
(3)变长参数
lua的函数可以接受不同数量的实参
function add(...)
-- body
local s = 0
for i,v in ipairs{...} do --注意这里是大括号
s = s + v
end
return s
end
print(add(3,4, 10, 25, 12)) --54
参数表中三个点(…)表示该函数可接受不同数量的实参。
表达式(…)的行为类似一个具有多重返回值的函数。
把第一个和第二个参数赋给a和b :local a, b = …
可以像访问数组一样去访问可变参数。
select(p1, p2):p1为数字n,那么select返回它第n个可变实参;p1为‘#’select返回变长参数的总数。
function fun( ... )
-- body
local len = select('#', ...) -- 获取长度
local params = {...}
for i=1,len do
print(params[i])
end
end
fun(3, 4, 10, 25, 12)
(4)具名实参
传递table
函数进阶
(1)匿名函数
在lua中,函数是一种第一类值,就是和其它传统类型一样可以存储到变量或table中,可以作为实参传递给其它函数,还可以作为其它函数的返回值。
函数与所有其它值一样都是“匿名”的:函数定义有一下两种方法,表明fun只是一个持有函数的变量,而不是函数的名称。
unction fun( ... )
-- body
end
fun = function( ... )
-- body
print('fun')
end
使用匿名函数:
local tb = {
{name = "grauna", level = "50"},
{name = "lua", level = "10"},
{name = "arraial", level = "30"}
}
table.sort( tb,
function(a, b) --匿名函数
return (a.name < b.name)
end)
print(tb[1].name)
print(tb[2].name)
print(tb[3].name)
table.sort用于对table中元素排序
(2)闭合函数
在函数内部定义的函数,能够通过建立一个闭合函数(closure),在外部函数已经执行完毕的情况下,还能访问到在外部函数中的局部变量。
后来发现一个规律:所有定义在函数内部的函数,都不能直接在外部函数外部访问,只能通过外部函数把内部函数返回出来,这样在外部函数的外部才可以使用,这也就是闭包函数通俗的理解吧。例如下面代码中的 c1、c2
function fun()
-- body
local i = 1
print(i);
return function() --返回了闭包函数
-- body
i = i+1
return i
end
end
c1 = fun() --创建闭合函数 c1
c2 = fun() --创建闭合函数 c2 注意:这里进行的操作其实是执行了fun函数,但并没有执行匿名函数,而是把匿名函数赋值给c1、c2了,所以c1()、c2()其实执行里面匿名函数
print(c1()) --也可以print(fun()())这样调用,print(fun())打印是fun函数里面的匿名函数的地址
print(c1())
print(c1())
--输出 1 2 3 4
在fun函数中匿名函数,仍能访问到fun作用域下的局部变量,i 对于匿名函数来讲被称作“非局部变量”。其中c1和c2是同一个函数创建的两个不同的closure,它们各自拥有局部变量的独立实例。
(3)非全局函数
函数可以存储在全局变量、局部变量、table字段中。只要将函数存到一个局部变量中,该函数只能在某个特定的作用域使用。
定义:
local a = function()
-- body
end
local function a()
-- body
end
(4)尾调用消除
尾调用:当 f 调用完 g 之后就再无其他事情可做了,这种情况下,当 g 返回时,执行控制权直接返回到调用 f 的那个点上。
消除:在尾调用之后,程序不需要保存任何关于该函数的栈信息了,使得在进行尾调用时不耗费任何栈空间。
function f()
-- body
print("f")
g() -- g()是函数f的最后调用
end