函数声明
function hello()
print('hello Lua')
end
hello()
注意,lua中的函数,不能用{}包起来,不然会报错的。
返回多个值
function test()
return 1, 2
end
test()
可变参数
function log(...)
-- 这里必须要这样赋值下,不过看官方文档里面好像没有这句,我自己跑没有这句报错
local arg = {...}
print('参数长度:' .. select('#', ...)) --> 参数长度:4
print('第一个参数:' .. select(1, ...)) --> 第一个参数:1
for k,v in ipairs(arg) do
print(k .. v)
end
end
log(1,2,3,4)
这里使用了lua中内置的一个函数select,select('#', ...) 表示获取参数的个数, select(n, ...) 表示获取可变参数中的第n个参数的值。
闭包
对,没错,就是js里面你理解的那个闭包,举个例子就行。
function createCounter()
i = 1;
return function()
i = i + 1
return i
end
end
counter = createCounter()
print(counter()) --> 2
print(counter()) --> 3
print(i) --> 3
注意上面的i是全局变量,如果你只想i在函数内部访问,使用local关键字来声明一个局部变量。
非全局函数
上面我们定义的其实都是全局函数,那怎么定义非全局函数呢?想想之前说过的table,我们可以在一个table对象上定义函数属性,这样来实现我们的效果。
方式一:
Lib = {
fun1 = function() return 1 end,
fun2 = function() return 2 end
}
print(Lib.fun1()) --> 1
print(Lib.fun2()) --> 2
方式二:
Lib = {
}
Lib.fun1 = function() return 1 end
Lib.fun2 = function() return 2 end
print(Lib.fun1()) --> 1
print(Lib.fun2()) --> 2
这个是不是跟js里面的对象很相似?
除了上面这种写法之外,Lua中还支持另外一种特殊的方式:
方式三:
Lib = {
}
function Lib.fun1() return 1 end
function Lib.fun2() return 2 end
print(Lib.fun1()) --> 1
print(Lib.fun2()) --> 2
我们也可以将函数存储到一个局部变量中,这样这个函数的作用范围就是跟这个局部变量一样的范围了。
do
local fun1 = function()
return 1
end
print(fun1()) --> 1
end
这里定义的fun1,只能在当前的do end块中可以访问到,外部无法访问。
定义局部函数lua中还支持另外一种方式:
do
local function fun1()
return 1
end
print(fun1()) --> 1
end
这两种方式一般情况下是等价的,除了递归。
来看个例子:
local fact = function (n)
if n == 0 then return 1
else return n*fact(n-1) -- 会报错
end
end
官方文档里面的说法是,在编译函数的时候,会发现fact此时还没有声明,然后报错。
下面这种方式就没有问题。
local function fact (n)
if n == 0 then return 1
else return n*fact(n-1)
end
end
当然,如果你非要像上面那样写,怎么办呢?也是可以的:
local fact
fact = function (n)
if n == 0 then return 1
else return n*fact(n-1) -- 会报错
end
end
就会先声明该函数变量,这个时候编译的时候就不会报错了,运行时函数变量已经赋值过了,所以不会有问题。
尾调用优化
function g() return 1;
function f() {
return g()
}
lua里面也有尾调用优化,如果不知道什么是尾调用优化,建议参考阮一峰老师的这篇文章 www.ruanyifeng.com/blog/2015/0… 尾调用优化就是说,如果函数结束的时候调用另外一个函数,那么就可以进行尾调用优化,就不需要保存当前函数的执行栈信息,因为这些信息后面根本用不到了。