Lua闭包

Lua中的闭包

闭包

闭包,又称词法闭包或函数闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例^wiki

Lua中闭包是一个由一个函数和该函数会访问到的upvalue组成的,其中的upvalue是指不是在局部作用范围内定义的一个变量,但同时又不是一个全局变量,在此内嵌函数的外层函数中定义的变量。

一个编程语言能够使用闭包的前提条件是:

  • 函数是一阶值
  • 函数可以嵌套定义
  • 可以捕获引用环境
  • 把引用环境和函数代码组成一个可调用的实体
  • 允许定义匿名函数

详细的闭包的介绍可以看这篇coolshell
理解Javascript的闭包

闭包的例子

在1中,count为函数counter的局部变量,由于内嵌函数(使用了此变量)的存在,导致此局部变量变成一种特殊的变量,upvalue,这个upvalue局部变量的一个引用,并不是一个拷贝。

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function counter()
    local count = 0

    return function
    count = count + 1
    print(count)

    end

    end

    c1 = counter()
    c1() // 1
    c1() // 2
    c2() = counter()
    c2() // 1
    c1() // 3

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function myClosure()
local num = 0

num_print = function()
print("The num is "..num..'\n')
end

num_inc = function()
num = num + 1
end

num_dec = function()
num = num - 1
end

num_reset = function(i)
num = i
end

return num_print, num_inc, num_dec, num_reset
end

local pr, inc, dec, reset = myClosure()
pr() //0
inc()
pr() //1
dec()
pr() //0
reset(666)
pr() //666

闭包的文章:
闭包的缺点
闭包的实践