6 Mor about Functions
Lua的函数没有名字,其所谓的名字只是一个标签
1
2
3
4
5
6a = {p = print}
a.p("Hello world!") --> Hello world
print = math.sin -- 'print' now refers to the sine function
a.p(print(1)) --> 0.841470
sin = a.p -- 'sin' now refers to the print function
sin(10, 20) --> 10 20函数构造语法糖:
1
function foo(x) return 2 * x end
可写作1
foo = function (x) return 2 * x end
anonymous function
table.sort()
的参数可以为无名函数1
2
3
4
5
6
7network = {
{name="grauna", IP="210.26.30.34"},
{name="arraial", IP="210.26.30.23"},
{name="lua", IP="210.26.23.12"},
{name="derain", IP="210.26.23.20"},
}
table.sort(network, function (a, b) return (a.name > b.name) end)
可用函数做参数的函数叫做higher-order function
- 导函数
1
2
3
4
5
6
7function derivative(f, delta)
delta = delta or 1e-4
return
function (x)
return (f(x + delta) - f(x)) / delta
end
end
返回值也是一个函数
Lua的函数可存储在table中,构造方法:
1
2
3
4
5
6
7
8
9
10Lib = {}
Lib.foo = function (x, y) return x + y end
Lib.goo = function (x, y) return x - y end
Lib = {
foo = function (x, y) return x + y end,
goo = function (x, y) return x - y end
}
Lib = {}
function Lib.foo(x, y) return x + y end
function Lib.goo(x, y) return x - y end递归局部函数
1
2
3
4local fact = function (n)
if n == 0 then return 1
else return n * fact(n - 1) -- buggy
end
在编译fact(n - 1)
时,局部函数fact()
尚未定义,其会去调用全局的函数,解决方法:先定义变量,再定义函数1
2
3
4
5
6local fact
fact = function (n)
if n == 0 then return 1
else return n * fact(n - 1)
end
end
- Lua会将局部函数语法糖拓展为递归安全形式
1
local function foo(<params>) <body> end
拓展为1
local foo; foo = function (<params>) <body> end
这一拓展对间接递归函数无效,这时需要手动修改1
2
3
4
5
6
7local f, g -- 'forward' declarations
function g()
<some code> f() <some code>
end
function f()
<some code> g() <some coe>
end
这里要注意function f()
不能写为local function f()
,否则Lua会拓展出新的f的定义而使之前的f()
未定义
- Lua利用
goto
实现尾调函数消除,从而无需额外的栈空间,所以嵌套尾调函数的调用次数无限制,不会出现栈溢出1
function f(x) return g(x) end
以下函数或语句无法消除1
2
3
4function f(x) g(x) end -- after calling g, f has to discard occasional results from g before returning
return g(x) + 1 -- must do the addition
return x or g(x) -- must adjust to 1 result
return (g(x)) -- must adjust to 1 result
由于Lua先求值再调用,所用尾调函数的表达式和参数表达式可以很复杂1
return x[i].foo(x[j] + a * b, i + j)