曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 2876|回复: 0
打印 上一主题 下一主题

upvalues 和 closures

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2014-12-6 19:35:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
upvalues 中文可以称之为外部局部变量,之所以称之为非局部,是因为当函数退出后,它仍然存在(正常情况下,局部变量会随着函数的退出也随之消失,因为函数栈也随之弹出),这说起来有点像 C 中的函数里的静态变量,却又不尽相同。

closures 中文可以称之为闭合函数

下面用实例来讲解这两个概念。

考察下面代码:
  1. function MakeLessThan(N)
  2.         return function(X)
  3.                 return X < N
  4.         end
  5. end

  6. LessThanFive = MakeLessThan(5)
  7. LessThanTen = MakeLessThan(10)

  8. print (LessThanFive(4))

  9. print (LessThanFive(5))

  10. print (LessThanTen(5))

  11. print (LessThanFive(9))

  12. 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 和 闭合函数:

一般来说,函数的局部变量会随着函数的退出而消失。但当该函数为闭合函数时,且当函数退出时,栈中的局部变量会被迁移到一个合适的地方保存起来。


再看另一个稍微特殊点的例子:
  1. function MakeGetAndInc(N)                -- 返回 N:
  2.                 local function Get()
  3.                         return N
  4.                 end
  5.                
  6.                 -- N + M
  7.                 local function Inc(M)
  8.                         N = N + M
  9.                 end
  10.                
  11.                 return Get, Inc
  12. end

  13. GetA, IncA = MakeGetAndInc(0)
  14. GetB, IncB = MakeGetAndInc(100)

  15. print (GetA())

  16. print (GetB())

  17. IncA(5)
  18. print (GetA())

  19. IncA(5)
  20. print (GetA())

  21. IncB(1)
  22. print (GetB())

  23. IncA(1)
  24. print(GetA())
复制代码

运行输出:
0
100
5
10
101
11






您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-4-28 00:40 , Processed in 0.058774 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表