• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >Lua > Lua中全局变量与非全局环境介绍

Lua中全局变量与非全局环境介绍

作者: 字体:[增加 减小] 来源:互联网

通过本文主要向大家介绍了lua 全局变量,lua定义全局变量,lua 全局函数,lua环境变量,lua环境变量配置pyhon等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

今天来聊两个话题——全局变量和非全局环境。

正如大家目前心里所感受到的,全局变量的内容很简单,而非全局环境的内容就稍微要锻炼一下脑细胞了。

1.全局变量的原形

在Lua中,要声明全局变量很简单,那就是定义变量的时候,前面不要加上local。

这个神秘的全局变量,其实本质上也是一个table,它把我们创建的全局变量都保存到一个table里了。

而这个table的名字是:_G
 
我们来看看代码:
    -- 定义一个全局变量
    gName = "哎哟,很挫哦";
  
    -- 用三种方式输出变量的值
    print(gName);
    print(_G["gName"]);
    print(_G.gName);
</div>

输出结果如下:
[LUA-print] 哎哟,很挫哦
[LUA-print] 哎哟,很挫哦
[LUA-print] 哎哟,很挫哦
</div>
我们定义了一个全局变量gName,于是这个gName成为了_G的一个字段。
怎么样,很简单吧。

2.非全局的环境

对于全局变量,不管到了哪个地方,哪种语言,大家总是会告诫说:“不要滥用,后果自负”
也许是因为这样,所以Lua有了一种比较特殊的机制:非全局环境。
我称它为“不会造成全局影响的全局变量”。

3.改变函数的全局变量环境——setfenv函数

先看看以下代码:
    -- 定义一个全局变量
    gName = "哎哟,很挫哦";
  
    -- 将当前全局环境重新设置为新的table
    setfenv(1, {});
  
    -- 输出值
    print(gName);
</div>
如果现在运行代码,输出结果将会是这样的:
[LUA-print] LUA ERROR: [string "src/main.lua"]:107: attempt to call global ‘print' (a nil value)
</div>
为什么?很出乎意料的脸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);
</div>

只要在定义新的环境时,把_G作为一个字段放到新的table里,就可以调用原来的全局变量了。

那么,输出结果如下:
[LUA-print] nil
[LUA-print] 哎哟,有点错哦
[LUA-print] 哎哟,很挫哦
</div>
三次调用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);
</div>

我们给新的table设置一个元表,这个元表的__index元方法就是_G。

于是,当新的环境里找不到print字段时,就会去_G里寻找。
 
输出结果如下:
[LUA-print] 别再哎哟了,很烦!
[LUA-print] 哎哟,很挫哦
</div>
第一次输出的是新环境里的gName值,第二次输出的是原来环境里的gName值,互不影响。

6.结束

好了,关于全局变量和非全局环境,就暂时说这么多。

虽然暂时还感觉不到有什么作用,没关系,后面还会有关于这部分的内容。

就像__index一样,是基础,后面可能会经常提到。

</div>

您可能想查找下面的文章:

  • 解析Lua中的全局环境、包、模块组织结构
  • 详解Lua中的变量相关知识点
  • Lua教程(十一):模块与包详解
  • Lua中创建全局变量的小技巧(禁止未预期的全局变量)
  • Lua极简入门指南:全局变量
  • Lua简介、编译安装教程及变量等语法介绍
  • Lua中全局变量与非全局环境介绍

相关文章

  • Lua基础教程之赋值语句、表达式、流程控制、函数学习笔记
  • Lua中算术运算符的使用示例
  • Lua中的模块与module函数详解
  • 在Lua中使用模块的基础教程
  • Nginx+lua 实现调用.so文件
  • Lua编程示例(四):Lua标准库之表库、字符串库、系统库
  • Lua获取系统时间和时间格式化方法及格式化参数
  • Lua和Nginx结合使用的超级指南
  • Lua面向对象之多重继承、私密性详解
  • Lua教程(六):绑定一个简单的C++类

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Lua面向对象之类和继承浅析
    • openresty中使用lua-nginx创建socket实例
    • 详解Lua中的数据类型
    • 详解Lua中的if语句的使用方法
    • Lua下基本的网络编程示例
    • Lua中的__index方法详解
    • lua脚本语言快速入门教程
    • Lua面向对象编程之类的简单实现方式
    • Mac平台中编译安装Lua运行环境及Hello Lua实例
    • Lua中关于元方法的一些知识点小结

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有