对lua中_ENV表的理解(lua5.2版本以后)
当我拿到_ENV表的时候,会去想这个_ENV表是干什么用的? 首先看如下代码:
print(_ENV) --0x1d005f0
print(_G) --0x1d005f0
ViewCode
看了上面的代码,就感觉_ENV表不就是_G表吗?但_ENV表是不是全局的呢?我又打印了_G表的内容:
for k , v in pairs(_G) do
print(k , v)
end
--[[
package table: 0xad1e50
setmetatable function: 0x419220
pairs function: 0x419380
require function: 0xad3900
loadfile function: 0x419540
print function: 0x418ce0
module function: 0xad3890
rawlen function: 0x418c50
load function: 0x419430
getmetatable function: 0x4195b0
type function: 0x418800
coroutine table: 0xad3970
table table: 0xad3d10
error function: 0x418f40
_VERSION Lua 5.2
debug table: 0xad4bb0
string table: 0xad2700
rawequal function: 0x418ca0
math table: 0xad64d0
tonumber function: 0x418870
bit32 table: 0xad2d60
os table: 0xad3c60
loadstring function: 0x419430
pcall function: 0x4191c0
io table: 0xad4030
select function: 0x418aa0
unpack function: 0x41fb40
collectgarbage function: 0x418fb0
xpcall function: 0x419110
rawset function: 0x418bb0
ipairs function: 0x4193a0
next function: 0x418e20
rawget function: 0x418c00
tostring function: 0x418840
arg table: 0xad76a0
_G table: 0xad15f0
assert function: 0x419680
dofile function: 0x419600
]]
发现_G表中的Key是没有_ENV表的,就比较疑惑?那_ENV到是什么,是怎么样产生的?关于这两个问题我看了lua闭包
的源码,lua闭包有两种生成方式,其中一种是在lua源码加载时,会生成闭包(ps:关于闭包的整体内容会在之后的另一篇博客讲),
对于该闭包它的第一个Upvalue就是_ENV,具体代码如下:
LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
const char *chunkname, const char *mode) {
ZIO z;
int status;
lua_lock(L);
if (!chunkname) chunkname = "?";
luaZ_init(L, &z, reader, data);
status = luaD_protectedparser(L, &z, chunkname, mode);
if (status == LUA_OK) { /* no errors? */
LClosure *f = clLvalue(L->top - ); /* get newly created function */
if (f->nupvalues >= ) { /* does it have an upvalue? */
/* get global table from registry */
Table *reg = hvalue(&G(L)->l_registry);
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
setobj(L, f->upvals[]->v, gt);
luaC_upvalbarrier(L, f->upvals[]);
}
}
lua_unlock(L);
return status;
}
lua_load中将注册表中的全局表(_G赋值给_ENV)
所以_ENV默认会指向_G表。至于_G表是如何创建的,各位可以参考这个博客。那_ENV表的作用是什么呢?
_ENV表的作用:表示当前代码块的环境,每一个代码块的环境都有一张_ENV。关于代码块的解释可以看这里。我们可以看一下下面这段代码就理解了:
function foorbar(env)
local _ENV = env
return function() print("yes") end
end print(_ENV) local l_test = foorbar({}) print(l_test()) --[[
table: 0x1a395f0
lua: code:3: attempt to call global 'print' (a nil value)
stack traceback:
code:3: in function 'l_test'
code:10: in main chunk
[C]: in ?
]]
上述可以看出,我们的所有内部函数都定义与一张_ENV表中,比如在print时实际上是_ENV.print(语法糖省略了),所以在代码块foorbar中_ENV被赋值为{},所以print就访问不到了。
所以_ENV表的作用实际上是充当环境,所以在5.2之后就没有全局变量这样一个说法(_ENV = _G还是有全局变量的)。这种做法类似于5.1的setfenv。关于如何实现setfenv在云风的博客有提及。
对lua中_ENV表的理解(lua5.2版本以后)的更多相关文章
- 【转载】Lua中实现类的原理
原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...
- Lua中table的实现-《Lua设计与实现》
本文来自<Lua设计与实现>的阅读笔记,推荐Lua学习者可以购买一本,深入浅出讲解lua的设计和实现原理,很赞,哈哈 Lua中对于表的设计,是基于数组和散列表,和其他语言不同,对于数组 ...
- lua中是 ffi 解析 【是如何处理数据包的/pkt是如何传进去的】 fsfsfs
lua中的ffi是如何解析的呢? 拿bcc中对proto的解析说起: metatype是有大学问的: ffi.metatype(ffi.typeof('struct ip_t'), { __index ...
- Cocos2d-x 脚本语言Lua基本数据结构-表(table)
Cocos2d-x 脚本语言Lua基本数据结构-表(table) table是Lua中唯一的数据结构.其它语言所提供的数据结构,如:arrays.records.lists.queues.sets等. ...
- Lua中的weak表——weak table
弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...
- Lua中的weak表——weak table(转)
弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...
- lua中常量的实现及表的深拷贝实现
废话:好久没在这里写博客了...主要原因是我买了个域名hanxi.info并在github上搭建了个人博客... lua中默认是没有c中的const常量的,在csdn上找到了一个使用setmetata ...
- 理解lua中 . : self
前言 在LUA中,经常可以看到:. self,如果你学习过Java或C#语言,可以这样理解 .对于c#和java的静态方法 :相当于是实例方法 今天在CSDN上看到一篇博客写的很清楚,转载过来 原文出 ...
- 两个函数彻底理解Lua中的闭包
本文通过两个函数彻底搞懂Lua中的闭包,相信看完这两个函数,应该能理解什么是Lua闭包.废话不多说,上 code: --[[************************************** ...
随机推荐
- (二)Jquery Mobile介绍以及Jquery Mobile页面与对话框
Jquery Mobile介绍以及Jquery Mobile页面与对话框 一. Adobe Dreamweaver CS6 环境 最新版本的cs6会支持JM的使用,有自动提示功能,很强大.安装说明地 ...
- (译)Windsor入门教程---第四部分 整合
介绍: 目前为止,已经介绍了应用程序的各个部分.首先是添加了Windsor程序集,然后是添加了控制器工厂,还添加了installer类来注册控制器.虽然但是我们还没用在应用程序中调用他们.在这 ...
- nginx 支持pathinfo
location ~ \.php { #去掉$ root H:/PHPServer/WWW; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.ph ...
- ICE BOX 配置,使用----第一篇
一 理论部分 (1) 为什么要使用icebox? icebox server代替了通常的server. icebox是为了方便集中管理多个ice服务而建立的. 它通过使用icebox服务器,把ice服 ...
- Android开发之FileProvider
最近做项目时,都需要用到FileProvider.于是就研究了下,现总结如下: 官方路径:http://developer.android.com/intl/zh-cn/training/secure ...
- Oracle 事件
Oracle 的事物 事物是设么 事物是用于高正数据的一致性,他由一组相关的dml语句组成(增加删除语句),这组语句要么全部成功要不全部失败. 如:网上转账. 1)设置保存点 Savepoint a1 ...
- scrollview嵌套gridview滑动问题
在开发过程总遇到ScrollView嵌套GridView,由于这两种控件都带有滚动条,当他们碰到一起的时候便会出问题,问题是gridview不滚动,并且只显示两行,为此看了官方文档,谷歌回答滚动里面没 ...
- Django performance
Reference: https://impythonist.wordpress.com/2016/02/21/building-high-performance-django-systems/ Th ...
- Linux搭建Tomcat
Linux系统运行确实很好,但是开发用,估计很少人用吧? 一.安装 1.下载tar.gz文件 2.解压,可以使用mv命令修改文件名 3.建立软连接: ln -s /usr/local/tomcat8. ...
- Bomb(hdu 3555)
题意:给定一个闭区间,求区间内有多少数中含"49" /* dp[i][j]表示i位数以j为最高位位中的所有不符合数的个数. 然后把数字拆分,乱搞即可. */ #include< ...