[Lua语言基础]-15、函数进阶_闭包函数

[复制链接]
查看3788 | 回复12 | 2021-8-21 17:20:32 | 显示全部楼层 |阅读模式
  1. --[===[闭包
  2. 一个函数中嵌套子函数,子函数可以使用父函数中的局部变量,这种行为就是“闭包”。
  3. 可以简略归纳为:闭包=函数+引用环境]===]

  4. -- 无参数闭包
  5. function Fun()
  6.         local i = 0                                -- i 变量,称为内嵌函数的“upValue”。这里的i 变量即不是全局变量,也不是局部变量。
  7.         -- 这里的称为“非局部变量”
  8.         print("-- A步骤 -- i=",i)
  9.         return function()                -- 内部嵌入的匿名函数,
  10.                 print("-- B步骤 -- i=",i)
  11.                 i = i+1
  12.                 print("-- C步骤 -- i=",i)
  13.                 return i
  14.         end
  15. end

  16. -- 调用测试
  17. f1 = Fun()
  18. print('调用一次',f1())
  19. print('调用二次',f1())
  20. print('调用三次',f1())
  21. --[===[输出结果:
  22. [2021:08:21-16:35:19:384] [函数进阶-闭包函数.lua 行号:9] -- A步骤 -- i= 0
  23. [2021:08:21-16:35:19:385] [函数进阶-闭包函数.lua 行号:11] -- B步骤 -- i= 0
  24. [2021:08:21-16:35:19:386] [函数进阶-闭包函数.lua 行号:13] -- C步骤 -- i= 1
  25. [2021:08:21-16:35:19:387] [函数进阶-闭包函数.lua 行号:20] 调用一次 1
  26. [2021:08:21-16:35:19:388] [函数进阶-闭包函数.lua 行号:11] -- B步骤 -- i= 1
  27. [2021:08:21-16:35:19:389] [函数进阶-闭包函数.lua 行号:13] -- C步骤 -- i= 2
  28. [2021:08:21-16:35:19:390] [函数进阶-闭包函数.lua 行号:21] 调用二次 2
  29. [2021:08:21-16:35:19:391] [函数进阶-闭包函数.lua 行号:11] -- B步骤 -- i= 2
  30. [2021:08:21-16:35:19:392] [函数进阶-闭包函数.lua 行号:13] -- C步骤 -- i= 3
  31. [2021:08:21-16:35:19:393] [函数进阶-闭包函数.lua 行号:22] 调用三次 3
  32. ]===]

  33. --[===[闭包的特点:
  34. 闭包中内嵌函数可以访问外部函数已经创建的所有局部变量,这些变量称为内嵌函数的“upValue”。
  35. 闭包与一般函数的区别:
  36. 闭包只是在形式上和表现上像函数,但是实际上不是函数。函数只有一个实例,定义后逻辑就确定了,不会执行时发生变化。    ]===]

  37. -- 带参数的闭包
  38. function FunWithPara(i)
  39.         print("步骤 1 ,i=",i)
  40.         return function()                        -- 内嵌匿名函数
  41.                 print("步骤 2 ,i=",i)
  42.                 i = i+1
  43.                 print("步骤 3 ,i=",i)
  44.                 return i
  45.         end
  46. end

  47. fun2 = FunWithPara(10)
  48. print(fun2())                                        -- 输出结果:11
  49. print(fun2())                                        -- 输出结果:12
  50. print(fun2())                                        -- 输出结果:13
  51. print(fun2())                                        -- 输出结果:14

  52. --[===[输出结果:
  53. [2021:08:21-16:37:19:177] [函数进阶-闭包函数.lua 行号:42] 步骤 1 ,i= 10
  54. [2021:08:21-16:37:19:180] [函数进阶-闭包函数.lua 行号:44] 步骤 2 ,i= 10
  55. [2021:08:21-16:37:19:183] [函数进阶-闭包函数.lua 行号:46] 步骤 3 ,i= 11
  56. [2021:08:21-16:37:19:184] [函数进阶-闭包函数.lua 行号:52] 11
  57. [2021:08:21-16:37:19:186] [函数进阶-闭包函数.lua 行号:44] 步骤 2 ,i= 11
  58. [2021:08:21-16:37:19:187] [函数进阶-闭包函数.lua 行号:46] 步骤 3 ,i= 12
  59. [2021:08:21-16:37:19:189] [函数进阶-闭包函数.lua 行号:53] 12
  60. [2021:08:21-16:37:19:190] [函数进阶-闭包函数.lua 行号:44] 步骤 2 ,i= 12
  61. [2021:08:21-16:37:19:193] [函数进阶-闭包函数.lua 行号:46] 步骤 3 ,i= 13
  62. [2021:08:21-16:37:19:194] [函数进阶-闭包函数.lua 行号:54] 13
  63. [2021:08:21-16:37:19:197] [函数进阶-闭包函数.lua 行号:44] 步骤 2 ,i= 13
  64. [2021:08:21-16:37:19:200] [函数进阶-闭包函数.lua 行号:46] 步骤 3 ,i= 14
  65. [2021:08:21-16:37:19:201] [函数进阶-闭包函数.lua 行号:55] 14
  66. ]===]

  67. -- 具备多个内嵌函数的闭包
  68. -- 本实例中,两个内嵌函数,对upValues 数值进行共享处理。
  69. function FunMutil()
  70.         local numUpValue = 10                        -- 这是“up Values”
  71.         function InnerFun1()                        -- 负责输出结果
  72.                 print(numUpValue)
  73.         end
  74.         function InnerFun2()                        -- 负责逻辑运算
  75.                 numUpValue = numUpValue + 100
  76.         end
  77.         return InnerFun1,InnerFun2
  78. end


  79. -- 调用测试
  80. local res1,res2 = FunMutil()
  81. res1()                                                                -- 输出结果:10
  82. res2()                                                                -- 输出结果:
  83. res1()                                                                -- 输出结果:110


  84. -- 带参数的内嵌函数
  85. function Fun4(num)
  86.         return function(value)                        -- 内嵌函数带有参数
  87.                 --return num * value                -- 此写法不能保存内部状态
  88.                 num = num*value
  89.                 return num
  90.         end
  91. end

  92. -- 调试测试
  93. fun4 = Fun4(10)
  94. print(fun4(3))                                                -- 输出结果:30
  95. print(fun4(3))                                                -- 输出结果:90
  96. print(fun4(3))                                                -- 输出结果:270


  97. -- 演示闭包可以具备多个实例。
  98. function Fun5()
  99.         local i = 0
  100.         return function()
  101.                 i=i+1
  102.                 return i
  103.         end
  104. end

  105. -- 调用测试
  106. res5_1 = Fun5()
  107. print(res5_1())                                                -- 输出结果:1
  108. print(res5_1())                                            -- 输出结果:2
  109. print(res5_1())                                      -- 输出结果:3

  110. res5_2 = Fun5()
  111. print(res5_2())                                         -- 输出结果:1
  112. print(res5_2())                                                -- 输出结果:2
  113. print(res5_2())                                                -- 输出结果:3


  114. --[===["词法域"概念
  115. 若将一个函数写在另一个函数内,那么这个位于内部的函数变可以访问,外部函数中的局部变量,
  116. 这项特征称之为“词法域”。外部函数中的局部变量在匿名函数内既不是全局变量,也不是局部
  117. 变量,将其称之为“非全局变量”(upValue)。

  118. 闭包的典型应用:
  119. “迭代器”的实现可以借助闭合函数实现,闭合函数能保持每次调用之间的一些状态。    ]===]


  120. -- 使用闭包技术开发自己的“迭代器”
  121. -- 自定义“迭代器”(闭包)
  122. function Itrs(tabArray)
  123.         local i = 0
  124.        
  125.         return function()
  126.                 i = i+1
  127.                 return tabArray[i]
  128.         end
  129. end

  130. -- 定义一个表
  131. myTab = {1,2,3,5,4,6,7,10,30,60,88}

  132. -- 迭代输出
  133. iterator = Itrs(myTab)
  134. -- 使用while 输出
  135. while true do
  136.         local j = iterator()
  137.     if j== nil then
  138.             break
  139.     end
  140.     print('while j=',j)
  141. end

  142. -- 使用for 输出
  143. for m in Itrs(myTab)do

  144. print('for: ',m)
  145. end

  146. --[===[
  147. 闭包的功能与作用总结:
  148.         1、开发自定义“迭代器”函数。
  149.     2.扩展了现有函数的功能。
  150.     3、扩展了命名空间
  151. ]===]

复制代码



回复

使用道具 举报

fojiao1992 | 2021-8-21 18:04:45 | 显示全部楼层
看不懂
回复

使用道具 举报

1974199655 | 2021-8-21 21:35:05 | 显示全部楼层
沙发
回复

使用道具 举报

Aitlo | 2021-8-21 22:42:03 | 显示全部楼层

对着视频看呗 看不懂才是对的
回复

使用道具 举报

905407220 | 2021-8-23 11:14:46 | 显示全部楼层

顶顶,学习了
回复

使用道具 举报

xywl | 2021-9-1 21:29:03 | 显示全部楼层
谢谢分享
回复

使用道具 举报

lijun0223 | 2021-10-30 10:42:56 | 显示全部楼层
回帖水经验!!!
回复

使用道具 举报

hitcsky | 2021-11-15 17:48:27 | 显示全部楼层
牛逼牛逼~
回复

使用道具 举报

z852975831 | 2021-12-2 17:02:24 | 显示全部楼层
什么时候用的上
回复

使用道具 举报

z852975831 | 2021-12-2 17:03:08 | 显示全部楼层
在水一个
在水一个
在水一个
在水一个
回复

使用道具 举报

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

本版积分规则