Lua学习笔记:对函数的深入理解
闭包
- lua中的函数都可以认为是闭包,只不过为了便于理解还是用了函数的概念。
- lua中函数的返回值可以是匿名函数,也就是闭包。以下面的代码为例,提出一个概念:非局部的变量。在下面的代码中,匿名函数访问了一个变量i,它对于newCount来说是局部变量,对于匿名函数来说是既不是局部变量也不是全局变量,在lua中这个称谓非局部的变量。
- 在lua中一个闭包指的是一个函数和该函数所需要访问的非局部的变量。lua会把它们看做是一个整体,因此在下面的代码中多次允许c1和c2,会发现变量i是在递增的。这是因为c1 = newCount()这句代码相当于给c1赋值了一个闭包,它包含了i这个变量。因此多次执行相当于就是在反复执行一个对象,这样i就一直是原来那个i。
1 | function () |
闭包的沙盒
- 下面这段代码中,修改了math库的sin方法。类似的还可以用来处理一些不安全的代码,这样的方式类似沙盒,将不安全包装了起来。
1
2
3
4
5
6
7
8print(math.sin(45))
oldSin = math.sin
math.sin = function (x)
return oldSin(x*math.pi/180)
end
print(math.sin(45))
递归
直接使用非全局的函数递归会报错,如下代码,会报:attempt to call global 'foo' (a nil value)
这个是因为在调用foo(x-1)时,这个foo函数还没有定义完,因此表达式在尝试调用一个全局的函数foo,但是显然这个全局函数是不存在的。
1 | local foo = function (x) |
正确写法
local foo
fool = function(x)
if x == 1 then
return 1
else
return x*foo(x-1)
end
end
-- 相当于
local function foo(x)
正确的尾调用本质是为了不记录函数的返回位置,这样在栈中就可以无限的调用函数。在lua中只有return