今天来聊两个话题——全局变量和非全局环境。
正如大家目前心里所感受到的,全局变量的内容很简单,而非全局环境的内容就稍微要锻炼一下脑细胞了。
1.全局变量的原形
在Lua中,要声明全局变量很简单,那就是定义变量的时候,前面不要加上local。
这个神秘的全局变量,其实本质上也是一个table,它把我们创建的全局变量都保存到一个table里了。
而这个table的名字是:_G
我们来看看代码:
复制代码 代码如下:
-- 定义一个全局变量
gName = "哎哟,很挫哦";
-- 用三种方式输出变量的值
print(gName);
print(_G["gName"]);
print(_G.gName);
输出结果如下:
复制代码 代码如下:
[LUA-print] 哎哟,很挫哦
[LUA-print] 哎哟,很挫哦
[LUA-print] 哎哟,很挫哦
我们定义了一个全局变量gName,于是这个gName成为了_G的一个字段。
怎么样,很简单吧。
2.非全局的环境
对于全局变量,不管到了哪个地方,哪种语言,大家总是会告诫说:“不要滥用,后果自负”
也许是因为这样,所以Lua有了一种比较特殊的机制:非全局环境。
我称它为“不会造成全局影响的全局变量”。
3.改变函数的全局变量环境——setfenv函数
先看看以下代码:
复制代码 代码如下:
-- 定义一个全局变量
gName = "哎哟,很挫哦";
-- 将当前全局环境重新设置为新的table
setfenv(1, {});
-- 输出值
print(gName);
如果现在运行代码,输出结果将会是这样的:
复制代码 代码如下:
[LUA-print] LUA ERROR: [string "src/main.lua"]:107: attempt to call global ‘print' (a nil value)
为什么?很出乎意料的脸print函数都无法找到了?
这是因为我们已经把当前函数范围内的全局变量环境改变了,全局变量默认是保存在_G中的,而现在的全局变量是在一个新的table里。
目前这个table是空的,所以不存在任何全局变量。
setfenv函数就是用来改变某个函数范围里的全局环境的,通俗地说,就是把某个函数范围内的_G给弄没了。
setfenv函数两个参数分别代表:
1). 第一个参数,可以是即将要改变环境的函数,也可以是一个数字。数字1代表当前函数,数字2代表调用当前函数的函数,后面以此类推。
2).第二个参数,新的全局环境table。
4.保留原来的_G
现在连print函数都无法使用了,对于测试很不方便,我们可以做个小动作,把原来的_G保留起来。
如下代码:
复制代码 代码如下:
-- 定义一个全局变量
gName = "哎哟,很挫哦";
-- 将当前全局环境重新设置为新的table
setfenv(1, {g = _G});
-- 输出值
g.print(gName);
-- 再次定义一个全局变量
gName = "哎哟,有点错哦";
-- 再次输出值
g.print(gName);
-- 输出原来的值
g.print(g.gName);
只要在定义新的环境时,把_G作为一个字段放到新的table里,就可以调用原来的全局变量了。
那么,输出结果如下:
复制代码 代码如下:
[LUA-print] nil
[LUA-print] 哎哟,有点错哦
[LUA-print] 哎哟,很挫哦
三次调用g.print函数的输出结果都是不一样的:
a.第一次,此时刚刚重新设置了全局环境,这时候当前函数的全局变量只有一个,那就是g,所以gName的值是nil。
b.第二次,我们再一次对gName进行赋值,此时,已经在新的环境中了,所以接下来输出的gName值是存在的。
c.第三次,这次输出的是g.gName的值,通过g调用的gName值是原先的全局环境里的值,所以gName的值仍然是最初的“哎哟,很挫哦”。
其实,这有什么用呢?倒不如直接用局部变量好了。
确实,从这例子里看不出什么特别的地方。
书里对于知识的介绍都是由浅入深的,所以这里暂时也没有更深入的介绍,看到后面内容的时候,我再继续和大家分享。
5.使用__index元方法保留原来的_G
这里还有一个小技巧分享一下,刚刚举例保留_G,但是调用print等函数时还需要形如g.print的方式,有点碍事。
我们可以利用__index来解决这个问题,如下代码:
复制代码 代码如下:
-- 定义一个全局变量
gName = "哎哟,很挫哦";
-- 一个table,即将成为新的环境
local newG = {};
setmetatable(newG, {__index = _G});
-- 将当前全局环境重新设置为新的table
setfenv(1, newG);
gName = "别再哎哟了,很烦!";
-- 输出值
print(gName);
print(_G.gName);
我们给新的table设置一个元表,这个元表的__index元方法就是_G。
于是,当新的环境里找不到print字段时,就会去_G里寻找。
输出结果如下:
复制代码 代码如下:
[LUA-print] 别再哎哟了,很烦!
[LUA-print] 哎哟,很挫哦
第一次输出的是新环境里的gName值,第二次输出的是原来环境里的gName值,互不影响。
6.结束
好了,关于全局变量和非全局环境,就暂时说这么多。
虽然暂时还感觉不到有什么作用,没关系,后面还会有关于这部分的内容。
就像__index一样,是基础,后面可能会经常提到。
Lua,全局变量,非全局环境
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 群星《赤热 电视剧音乐原声》[320K/MP3][427.21MB]
- 周华健.1996-爱的光【滚石】【WAV+CUE】
- 杨宗宪.1996-想啥人怨啥人等啥人【有容唱片】【WAV+CUE】
- 郑秀文.2024-Best.Concert.Live【华纳】【FLAC分轨】
- 《Pax Dei》配置要求一览
- 《过山车之心2》存档位置介绍
- 《三国志8 REMAKE》评测:自定义的三国演义
- 群星《少年白马醉春风 网剧OST原声专辑》[320K/MP3][117.05MB]
- 群星《少年白马醉春风 网剧OST原声专辑》[FLAC/分轨][621.04MB]
- 《魏佳艺5CD合集》[WAV分轨][3.8G]
- CSGO职业选手donk怎么样 2024最新donk个人资料介绍
- CSGO职业选手NiKo怎么样 2024最新Niko个人资料介绍
- 剑网3丝路风语PVE焚影怎么打 丝路风语PVE焚影圣诀手法配装攻略
- [老虎魚古典名盘]心碎SACD浪漫小提琴之声[DSF]
- Queen(皇后乐队)《GreatestHitsII》[SACD-DSF]