当我拿到_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版本以后)的更多相关文章

  1. 【转载】Lua中实现类的原理

    原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...

  2. Lua中table的实现-《Lua设计与实现》

    本文来自<Lua设计与实现>的阅读笔记,推荐Lua学习者可以购买一本,深入浅出讲解lua的设计和实现原理,很赞,哈哈   Lua中对于表的设计,是基于数组和散列表,和其他语言不同,对于数组 ...

  3. lua中是 ffi 解析 【是如何处理数据包的/pkt是如何传进去的】 fsfsfs

    lua中的ffi是如何解析的呢? 拿bcc中对proto的解析说起: metatype是有大学问的: ffi.metatype(ffi.typeof('struct ip_t'), { __index ...

  4. Cocos2d-x 脚本语言Lua基本数据结构-表(table)

    Cocos2d-x 脚本语言Lua基本数据结构-表(table) table是Lua中唯一的数据结构.其它语言所提供的数据结构,如:arrays.records.lists.queues.sets等. ...

  5. Lua中的weak表——weak table

    弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...

  6. Lua中的weak表——weak table(转)

    弱表(weak table)是一个很有意思的东西,像C++/Java等语言是没有的.弱表的定义是:A weak table is a table whose elements are weak ref ...

  7. lua中常量的实现及表的深拷贝实现

    废话:好久没在这里写博客了...主要原因是我买了个域名hanxi.info并在github上搭建了个人博客... lua中默认是没有c中的const常量的,在csdn上找到了一个使用setmetata ...

  8. 理解lua中 . : self

    前言 在LUA中,经常可以看到:. self,如果你学习过Java或C#语言,可以这样理解 .对于c#和java的静态方法 :相当于是实例方法 今天在CSDN上看到一篇博客写的很清楚,转载过来 原文出 ...

  9. 两个函数彻底理解Lua中的闭包

    本文通过两个函数彻底搞懂Lua中的闭包,相信看完这两个函数,应该能理解什么是Lua闭包.废话不多说,上 code: --[[************************************** ...

随机推荐

  1. swfobject.embedSWF属性与用法

    JS+flash的焦点幻灯片既能大方得体的展示焦点信息,也能美轮美奂的展示图片,越来越多的网站使用这种焦点幻灯的表现方法.很多童鞋在下载这方面的素材代码的时候,往往会因为展示出来的是flash,觉得难 ...

  2. POJ 2482 Stars in Your Window

    线段树+离散化+扫描线 AC之后,又认真读了一遍题目,好文章. #include<cstdio> #include<map> #include<algorithm> ...

  3. ftp linux-500 OOPS问题解决-jooyong-ChinaUnix博客

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  4. svn + jenkins + maven 实现java环境的自动化构建和部署

    1. 环境说明: 系统CentOS 7 x64 IP:  10.6.0.126 1.1 首先安装配置 svn Centos 7  通过yum 安装svn 既可, 版本为1.7.14 # yum -y ...

  5. url语法

    URL的主要部分 URL通常被写成如下形式: <方案>:<方案描述部分> 一个URL包含了它使用的方案名称(<方案>), 其后紧跟一个冒号,然后是一个字符串 (&l ...

  6. WIN32动态链接库设计与使用

    WINDOWS动态链接库技术能很好地实现代码的分模块,综合来说,windows动态链接库分为三种WIN32动态链接库,使用WINDOWS api函数调用设计,贴近底层,体积小,是最初Windows程序 ...

  7. memcache数据组织

    转自:原链接 使用命令 set(key, value) 向 memcached 插入一条数据, memcached 内部是如何组织数据呢 一 把数据组装成 item memcached 接受到客户端的 ...

  8. iOS第三方常用类库

    1.AFNetworking AFNetworking 采用 NSURLConnection + NSOperation, 主要方便与服务端 API 进行数据交换, 操作简单, 功能强大, 现在许多人 ...

  9. [bzoj1195] [hnoi2006] 最短母串

    本题是一个经典的状压dp问题,在紫书中有着加强版的例题. 本题的难度主要体现在:如何输出字符串字典序最小. 为了解决这个问题,我们有两种常用方案: 1) 我们可以采用bfs输出路径的方法,使用+1来输 ...

  10. Java中的条件编译(转)

    源:Java中的条件编译 一直以来,不知道怎么在Java中实现像C/C++一样的#ifdef...#endif这样的预编译宏,致使Java代码中一直用if判断,刚好刚才看到了解决办法,记录一下. C/ ...