微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

LUA闭包

function newCounter()
     local i = 0
     return function () -- 匿名函数
          i = i + 1
          return i
     end
end
 
c1 = newCounter()
print(c1()) 
print(c1())
闭包=函数+引用环境。上述代码中的newCounter函数返回了一个函数,而这个返回的匿名函数就是闭包的组成部分中的函数;引用环境就是变量i所在的环境。实际上,闭包只是在形式和表现上像函数,但实际上不是函数,我们都知道,函数就是一些可执行语句的组合体,这些代码语句在函数被定义后就确定了,并不会再执行时发生变化,所以函数只有一个实例。而闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例,就好比相同的类代码,可以创建不同的类实例一样。在看别人的文章时,看到有这样的说法:子函数可以使用父函数中的局部变量,这种行为就叫做闭包!这种说法其实就说明了闭包的一种表象,让我们从外在形式上,能更好的理解什么是闭包。

function Fun1()
     local iVal = 10          -- upvalue
     function InnerFunc1()     -- 内嵌函数
          print(iVal)          --
     end
 
     function InnerFunc2()     -- 内嵌函数
          iVal = iVal + 10
     end
 
     return InnerFunc1,InnerFunc2
end
 
-- 将函数赋值给变量,此时变量a绑定了函数InnerFunc1,b绑定了函数InnerFunc2
local a,b = Fun1()
-- 调用a
a()          -->10
-- 调用b
b()          -->在b函数修改了upvalue iVal
-- 调用a打印修改后的upvalue
a()          -->20

上述这段简单的代码,就验证了在内嵌函数中是共享upvalue的,就好比C++类中的成员函数可以访问和修改成员变量一样。


使用闭包

可以看到闭包是数据和行为的结合体,就好比C++中的类,这样就使得闭包具有较好的抽象能力,在某些场合下,我们需要记住某次调用完成以后数据的状态,就好比C++中的static类型的变量,每次调用完成以后,static类型的变量并不会被清除。使用闭包就可以很好的完成该功能,在下一篇博文中,我将会讲到使用闭包完成迭代器功能

总结

闭包是一个非常很总要的概念,也好理解,也难理解,简单的说,闭包就是内嵌的函数加上它可以正确访问的upvalue。很多时候,我们明白了这个道理,却不会用这个东西,所以,我们需要阅读更多的代码,参加更多的项目,去积累更多的项目经验,来丰富自己的阅历,到时候,理解层次就会上去。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐