lua编程 全局变量 环境 模块

本文详细解析了Lua中全局变量的存储方式及其环境变化的影响,并介绍了如何通过setfenv及require进行函数作用域的更改与模块加载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.youkuaiyun.com/leonwei/article/details/7739930


1.全局变量与环境

lua中真正存储全局变量的地方不是在_G里面,而是在setfenv(i,table)的table中,所有当前的全局变量都在这里面找,只不过在程序开始时lua会默认先设置一个变量

_G=这个里面的table而已。所以在新设置环境后,如果还想找到之前的全局变量,通常需要附加上为新的table设置元表{_index=_G}

下面的几个例子:

a=1
print(a)
print(_G.a)
--正常情况,输出1,1


a=1
setfenv(1,{})
print(a)
print(_G.a)
--这时会出错说找不到print,因为当前的全局变量表示空的,啥也找不到的

a=1
setfenv(1,{_G=_G})
_G.print(_G.a)

print(a)

--这时_G.print(_G.a)可以正常吗,因为可以在新的table中找到一个叫_G的表,这个_G有之前的奈尔全局变量,但是下面的print(a)则找不到print,因为当前的table{_G=_G}没有一个叫print的东西


local mt={__index=_G}
local t={}
setmetatable(t,mt)
setfenv(1,t)
print(a)
print(_G.a)

--这是正确输出,因为新的全局表采用之前的表做找不到时的索引,原先的表里面存在print 、_G、 a这些东西


setfenv的第一个参数可以是当前的堆栈层次,如1代表当前代码块,2表调用当前的上一层,也可以是具体的那个函数名,表示在那个函数里。

每个新创建的函数都将继承创建它的那个函数的全局环境


2.require

require的意义就是导入一堆可用的名称,这些名称(非local的)都包含在一个table中,这个table再被包含在当前的全局表(“通常的那个_G”)中,这样访问一个模块中的变量就可以使用_G.table.**了,(刚开始学习lua时还以为模块里的名称在导入后直接就是在_G中的)


a=require("")的a取决于这个导入的文件的返回值,没有返回值时true,所以在标准的情况下模块的结尾应该return这个模块的名字,这样a就是这个模块的table了(当然不这样做也ok,只是a就不是这个模块名了)



转自:http://blog.youkuaiyun.com/icyday/article/details/8116818

setenv是在lua5.1中有的改变函数作用域的函数。

用法是setenv(func or number,tbl),第一个参数可以是数字也可以是函数,数字1表示当前的作用于,2表示上一层的作用域,特殊情况0,setfenvchanges the environment of the running thread. In this case,setfenv returns no values.此时是不返回的,其他情况都返回第一个参数指向的函数(被他坑了好久,以为不返回!!因为我只看文档的最后也就是0的特殊情况!!!)

可以用来做模块加载来使用

[plain]  view plain copy
  1. local FuncEnv={}  
  2. setmetatable(FuncEnv, {__index = _G})  
  3. local func=loadfile("a.lua")  
  4. setfenv(func,FuncEnv)()--等价于setenv(func,FuncEnv);func();  
  5. FuncEnv.Test()--FuncEnv就是新的模块啦,可以用其中的函数啦,其实,lua内部的model命令或者函数也是用的这个原理  

其中a.lua为如下:
[plain]  view plain copy
  1. function test()  
  2.     print("Test")  
  3. end  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值