引言:
什么是闭包,闭包等不等于函数,upvalue从何而来,upvalue是指针还是值?
function a()
local p = 10
local function b()
p = p + 1
print("this is func b")
print("upvalue params", p )
end
return b
end
b = a()
b() -- 11
b() -- 12
针对上面的栗子:
- 函数b叫做函数a的内嵌函数(inner function)
- 函数a叫做函数b的外包函数(lexical function)
- 变量p内嵌函数的外部局部变量(external local variable),即upvalue
闭包
闭包是什么?闭包是否等于函数?
记住下面的公式:
闭包 = 函数 + 环境
PS: 环境主要是指upvalue
c = a(); c, b的函数是一样的,但是upvalue不同,所以当b执行返回值为12的时候,c执行还是11.
因此,相同函数 == 同一个闭包
upvalue究竟是值传递,还是指针传递?
先看一段源码:
typedef struct UpVal {
CommonHeader;
TValue *v; /*points to stack or to its own value */
union {
TValue value; /* the value(when closed)*/
struct { /* double linked list(when open))*/
struct UpVal *prev;
struct UpVal *next;
}l;
}u;
}
upvalue存在2中状态: closed and open。
- open:执行环境还未销毁,此时使用指针引用到相应的变量即可。
- closed:执行环境后已经销毁,需要把值保存到TValue value中,此时已经不再是指针了。
举个栗子,还是这段代码:
function a()
local p = 10
local function b()
p = p + 1
print("upvalue params", p )
end
b()
return b
end
b = a()
b()
分析:
b = a(); 执行该行代码的时候,a调用b,此时a未被销毁,p对于b就是open的,此时使用TValue *v保存p的指针。
b(); 执行该行代码的时候,a已经调用结束,此时p对于b就是closed的,p保存在TValue value中,不再是指针。
PS: 想了解lua对upvalue 的处理逻辑,可以阅读源码: lvm.c中closure创建,lfunc.c中 luaF_findupval, luaF_close