Lua复习之何为闭包

闭包=函数+引⽤环境

⼦函数可以使⽤⽗函数中的局部变量,这种⾏为可以理解为闭包!

bash 复制代码
local function foo() 
  local i = 1 
  local function bar() 
    i = i + 1 
    print(i) 
  end 
  return bar
end
local fn = foo()
print(fn()) -- 2'

你可以看到, bar 这个函数可以读取函数 foo 里面的局部变量 i,并修改它的值,即使这个变量并不在 bar 里面定义。这个特性叫做词法作用域

事实上,lua的这些特征正是闭包的基础。所谓闭包,简单地理解,它其实是一个函数,不过它访问了另外一个函数词法作用域中的变量。

如果按照闭包的定义来看,Lua 的所有函数实际上都是闭包,即使你没有嵌套。这是因为 Lua 编译器会把 Lua 脚本外面,再包装一层主函数。比如下面这几行简单的代码段:

bash 复制代码
local foo, bar
local function fn()
  foo = 1
  bar = 2
end

被编译后就会变成这样:

bash 复制代码
function main(...)
  local foo, bar
  local function fn()
    foo = 1
    bar = 2
  end
end

而函数 fn 捕获了主函数的两个局部变量,因此也是闭包。

闭包总结

闭包的主要作用有两个,一是简洁,不需要在不使用时生成对象,也不需要函数名;二是捕获外部变量形成不同的调用环境

闭包原理概述:

闭包(函数)编译时会生成原型(prototype),包含参数、调试信息、虚拟机指令等一系列该闭包的源信息,其中在递归编辑内层函数时,会为内层函数生成指令,同时为该内层函数需要的所有upvalue创建表,以便之后调用时进行upvalue值搜索

在lua中,会生成一个全局栈,所有的upvalue都会指向该栈中的值,若对应的参数离开的作用域,栈中的值也会被释放,upvalue的指针会指向自己,等待被gc

闭包运行时,会通过创建指向upvalue的指针,并循环upvalue linked list,找到所需要的外部变量进行运行.

说到Upvalue 那何为Upvalue呢?

bash 复制代码
local function foo() 
  local i = 1 
  local function bar() 
    i = i + 1 
    print(i) 
  end 
  return bar
end
local fn = foo()
print(fn()) -- 2'

当我们写闭包时,这个子函数所调用父函数里面的local变量 i 就是upvalue。当bar引用 i 时Lua就会自动将i升级为 Upvalue。 并且为其创建表,以便之后调用时进行upvalue值搜索。

  • 在lua中,会生成一个全局栈,所有的upvalue都会指向该栈中的值,若对应的参数离开的作用域,栈中的值也会被释放,upvalue的指针会指向自己,等待被gc
  • 闭包运行时,会通过创建指向upvalue的指针,并循环upvalue linked list,找到所需要的外部变量进行运行
  • 一个upvalue有两种状态:open和closed。当一个upvalue被创建时,它是open的,并且它的指针指向Lua栈中对应的变量。当Lua关闭了一个upvalue,upvalue指向的值被复制到upvalue结构内部,并且指针也相应进行调整
相关推荐
北方有星辰zz30 分钟前
数据结构:栈
java·开发语言·数据结构
我是唐青枫1 小时前
C#.NET NLog 详解
开发语言·c#·.net
向宇it1 小时前
【unity游戏开发——网络】网络游戏通信方案——强联网游戏(Socket长连接)、 弱联网游戏(HTTP短连接)
网络·http·游戏·unity·c#·编辑器·游戏引擎
Mr_Xuhhh1 小时前
网络基础(1)
c语言·开发语言·网络·c++·qt·算法
旺旺大力包1 小时前
【JS笔记】JS 和 noodjs 的常见操作(十)
开发语言·javascript·node.js·ecmascript
背影疾风2 小时前
C++之路:类基础、构造析构、拷贝构造函数
linux·开发语言·c++
Ting-yu2 小时前
Java中Stream流的使用
java·开发语言·windows
【ql君】qlexcel3 小时前
Notepad++ 复制宏、编辑宏的方法
开发语言·javascript·notepad++··宏编辑·宏复制
Zevalin爱灰灰3 小时前
MATLAB GUI界面设计 第六章——常用库中的其它组件
开发语言·ui·matlab
冰糖猕猴桃3 小时前
【Python】进阶 - 数据结构与算法
开发语言·数据结构·python·算法·时间复杂度、空间复杂度·树、二叉树·堆、图