当我拿到_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. Sublime Text 3 搭建 Golang 开发环境

    安装Golang go语言主页: https://golang.org/ go语言安装下载: https://golang.org/dl 环境变量设置: GOROOT: GOROOT变量设置go安装的 ...

  2. 高并发数据库之MySql性能优化

    1.慢查询 SHOW VARIABLES LIKE '%quer%'

  3. php new self 详解(转)

    self points to the class in which it is written. So, if your getInstance method is in a class name M ...

  4. 哈夫曼树压缩C#算法(huffman)

    算法原理:http://www.cnblogs.com/skywang12345/p/3706833.html. 上代码: using System; using System.Collections ...

  5. ios中操作技巧

    1.配置字段快捷键: @property(nonatimic,copy) NSString *<#param#>; 2.NSNumber 转NSString 最快简单方式: NSNumbe ...

  6. Mariadb galera 群集

    环境:  CentOS 7 x64  *  3 IP : 192.168.0.100 IP : 192.168.0.101 IP : 192.168.0.102 配置mariadb YUM 源 htt ...

  7. Sping--自动装配(byname, bytype)

    UserDAOImpl.java: package com.bjsxt.dao.impl; import com.bjsxt.dao.UserDAO; import com.bjsxt.model.U ...

  8. iOS校验身份证是否合法

    //身份证号验证 1900+/2000+的年份日期的正则表达式经过修改,目前貌似是对的,如果哪位朋友发现错误希望能够给与提示 //返回yes位表示格式正确,否则为错误 -(BOOL)IDCardAut ...

  9. AFNetworking封装思路简析

    http://blog.csdn.net/qq_34101611/article/details/51698473 一.AFNetworking的发展 1. AFN 1.0版本 AFN 的基础部分是 ...

  10. ios 自定义NSError

    from:[object-c错误处理]http://www.androiddev.net/objective-c%E5%AD%A6%E4%B9%A0%E4%B9%8B%E9%94%99%E8%AF%A ...