对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: --[[************************************** ...
随机推荐
- 如何编译生成 dll
原文:http://blog.csdn.net/qianchenglenger/article/details/21599235 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[ ...
- php的几个内置的函数
// 取得所有的后缀为PHP的文件 $files = glob(‘*.php’); print_r($files); j
- 在MyEclipse8.6中设置jQuery自动提示 - 肖飞figo的云计算专栏 - 博客频道 - CSDN.NET
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- HDU 2412 Party at Hali-Bula
树形DP水题.判断取法是否唯一,dp的时候记录一下每个状态从下面的子节点推导过来的时候是否唯一即可. #include<cstdio> #include<cstring> #i ...
- macbook pro 突破校园网inode客户端限制分享网络
[原创] 环境: 1. macbook pro (retina) 2. mac os x 10.9 3. H3C inode for mac 7.0 分享方法: 1.打开inode联网. 2.打开设置 ...
- HUST 1354 Rubiks
背包.注释写详细了. 本想这样写:每个组内各自做背包,然后组间做背包,但是由于这题M=10000,时间复杂度太大. #include<cstdio> #include<cstring ...
- Masonry布局框架的使用
Masonry是一个轻量级的布局框架 拥有自己的描述语法 采用更优雅的链式语法封装自动布局 简洁明了 并具有高可读性.比我们使用自动布局,繁琐的约束条件,好用多了.下面我们来学学masonry的使用方 ...
- Maven项目中pom文件分析
pom英文全称: project object model 1.概述 pom.xml文件描述了maven项目的基本信息,比如groupId,artifactId,version等.也可以对maven项 ...
- IOS开发-UI学习-UITabBarController的使用
UITabBarController具体实例如下图 我们最常见的就是微信最下面的四个按钮,通过这四个按钮可以导航到不同的界面. UITabBarController是一个容器,以下的例程中给UITab ...
- Linux 下如何安装 JDK ,以 Ubuntu 为例。
http://www.cnblogs.com/memory4young/p/ubuntu-install-jdk.html 一.下载 首先,当然是要下载了. 地址:http://www.oracle. ...