曲径通幽论坛
标题:
upvalues 和 closures
[打印本页]
作者:
beyes
时间:
2014-12-6 19:35
标题:
upvalues 和 closures
upvalues
中文可以称之为
外部局部变量
,之所以称之为非局部,是因为当函数退出后,它仍然存在(正常情况下,局部变量会随着函数的退出也随之消失,因为函数栈也随之弹出),这说起来有点像 C 中的函数里的静态变量,却又不尽相同。
closures
中文可以称之为
闭合函数
。
下面用实例来讲解这两个概念。
考察下面代码:
function MakeLessThan(N)
return function(X)
return X < N
end
end
LessThanFive = MakeLessThan(5)
LessThanTen = MakeLessThan(10)
print (LessThanFive(4))
print (LessThanFive(5))
print (LessThanTen(5))
print (LessThanFive(9))
print (LessThanTen(9))
复制代码
运行输出:
true
false
true
false
true
分析
:
注意,每一次调用 MakeLessThan() 函数时,都会创建一个新的局部变量 N 。按照一般情况,当 MakeLessThan() 返回时,局部变量应该也随之消失。然而,这里却不会这样!原因是,在 MakeLessThan() 里还有一个匿名函数要返回,这个匿名函数又会使用 MakeLessThan() 中的变量 N ,因此就不能使得 N 随着 MakeLessThan() 的退出而消失。
在
LessThanFive = MakeLessThan(5)
这条语句中,MakeLessThan() 将匿名函数返回到 LessThanFive 中。在后面的几条比较语句中,我们都可以看到 N 的持续存在。
当一个函数中的局部变量位于另一个范围(匿名函数)之上时,那么该变量称之为 “
外部局部变量
” 或 “
upvalue
” 。
一个函数含有一个或多个 upvalue 时,则称该函数为 “闭合函数” (closure)。
可以这么理解 upvalue 和 闭合函数:
一般来说,函数的局部变量会随着函数的退出而消失。但当该函数为闭合函数时,且当函数退出时,栈中的局部变量会被迁移到一个合适的地方保存起来。
再看另一个稍微特殊点的例子:
function MakeGetAndInc(N) -- 返回 N:
local function Get()
return N
end
-- N + M
local function Inc(M)
N = N + M
end
return Get, Inc
end
GetA, IncA = MakeGetAndInc(0)
GetB, IncB = MakeGetAndInc(100)
print (GetA())
print (GetB())
IncA(5)
print (GetA())
IncA(5)
print (GetA())
IncB(1)
print (GetB())
IncA(1)
print(GetA())
复制代码
运行输出:
0
100
5
10
101
11
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/)
Powered by Discuz! X3.2