Kiritow的学园 2014-09-23
一、函数
在Lua中,函数是作为"第一类值"(First-Class Value),这表示函数可以存储在变量中,可以通过参数传递给其他函数,或者作为函数的返回值(类比C/C++中的函数指针),这种特性使Lua具有极大的灵活性。
Lua对函数式编程提供了良好的支持,可以支持嵌套函数。
另外,Lua既可以调用Lua编写的函数,还可以调用C语言编写的函数(Lua所有的标准库都是C语言写的)。
定义一个函数
代码如下:
function hello()
print('hello')
endhello函数不接收参数,调用:hello(),虽然hello不接收参数,但是还可以可以传入参数:hello(32)
另外如果只传递一个参数可以简化成functionname arg的调用形式(注意数值不行)
代码如下:
> hello '3'
hello
> hello {}
hello
> hello 3
stdin:1: syntax error near '3'代码如下:
> a = 21 > print a stdin:1: syntax error near 'a'
代码如下:
> function f(n) >> n = n or 0 >> print(n) >> end > f() 0 > f(1) 1
Lua支持返回多个值,形式上非常类似Python:
代码如下:
> function f() >> return 1,2,3 >> end > a,b,c = f() > print(a .. b .. c) 123
代码如下:
> t = {f()}
> print(t[1], t[2], t[3])
1 2 3 代码如下:
> t = {f(), 4}
> print(t[1], t[2], t[3])
1 4 nil代码如下:
> t = {f(), f()}
> print(t[1], t[2], t[3], t[4], t[5])
1 1 2 3 nil代码如下:
> function g() >> end > print(g()) > print((g())) nil
代码如下:
> print((f())) 1 > print(f()) 1 2 3
二、变长参数
Lua支持编程参数,使用简单(借助于table、多重赋值)
代码如下:
> function f(...)
for k,v in ipairs({...}) do
print(k,v)
end
end
> f(2,3,3)
1 2
2 3
3 3代码如下:
> function sum3(...) >> a,b,c = ... >> a = a or 0 >> b = b or 0 >> c = c or 0 >> return a + b +c >> end > =sum3(1,2,3,4) 6 > return sum3(1,2) 3
select('#', …)返回可变参数的长度,select(n,…)用于访问n到select('#',…)的参数
代码如下:
> =select('#', 1,2,3)
3
> return select('#', 1,2, nil,3)
4
> =select(3, 1,2, nil,3)
nil 3
> =select(2, 1,2, nil,3)
2 nil 3三、函数式编程
函数做一个First-Class Value可以赋值给变量,用后者进行调用
代码如下:
> a = function() print 'hello' end > a() hello > b = a > b() hello
代码如下:
> g = function() return function() print 'hello' end end > g()() hello
代码如下:
> g = function(a) return function() print('hello'.. a); a = a + 1 end end
> f = g(3)
> f()
hello3
> f()
hello4四、局部函数
局部函数可以理解为在当前作用域有效的函数,可以用local变量来引用一个函数:
代码如下:
> do >> local lf = function() print 'hello' end >> lf() >> end hello > lf() stdin:1: attempt to call global 'lf' (a nil value) stack traceback: stdin:1: in main chunk [C]: in ?
需要注意的是,对于递归函数的处理
代码如下:
> do local lf = function(n) if n <= 0 then return end print 'hello' n = n -1 lf(n) end lf(3) end hello stdin:8: attempt to call global 'lf' (a nil value) stack traceback: stdin:8: in function 'lf' stdin:9: in main chunk [C]: in ?
代码如下:
do local lf; lf = function(n) if n <= 0 then return end print 'hello' n = n -1 lf(n) end lf(3) end hello hello hello
代码如下:
> do local function lf(n) if n <= 0 then return end print 'hello' n = n -1 lf(n) end lf(3) end hello hello hello > lf(3) stdin:1: attempt to call global 'lf' (a nil value) stack traceback: stdin:1: in main chunk [C]: in ?
五、尾调用
所谓尾调用,就是一个函数返回另一个函数的返回值:
代码如下:
function f() … return g() end
代码如下:
> function f(n) >> if n <= 0 then >> return 0 >> end >> a = f(n-1) >> return n * a >> end > f(10000000000) stdin:5: stack overflow stack traceback: stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' ... stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:5: in function 'f' stdin:1: in main chunk [C]: in ?
代码如下:
function f(n, now) if n <= 0 then return now end return f(n-1, now*n) end f(10000000000, 1)