【Lua进阶系列】环境ENV

本文介绍了Lua中的全局环境_G和非全局环境_ENV的概念。_G作为全局变量的容器,可以通过元表防止未声明的全局变量。而在Lua5.2以后,_ENV成为函数环境的上值,通过这种方式实现类似命名空间的效果,避免全局污染和同名函数冲突。文章探讨了使用_ENV的益处,并提到如何通过loadfile创建新环境以增强安全性。

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

             【Lua进阶系列】环境ENV

   

    大家好,我是Lampard猿奋~~

    欢迎来到Lua进阶系列的博客,今天和大家分享一下lua中关于环境的一些知识

  

 (一)全局环境_G

        lua使用一个表来保存全局变量,一方面简化了Lua语言内部的实现,另一方面可以像操作一个普通表一样操作这个表。lua把全局环境本身保存到全局变量_G中(因此_G._G 和 _G是等价的),我们可以通过_G来访问/设置全局变量。

   

         Lua中的全局变量不需要声明就可以使用,虽然这种行为对于小程序来说可能会比较方便。但是对于大型项目来说可能会引起一些BUG,因为_G就是一个表结构,因此我们可以利用元表的机制来避免这种情况。

         对不存在的key赋值:

        访问不存在的key:

      那么如果我们需要声明一个新的全局变量的时候,使用rawset函数就可以了。rawset可以绕过元方法直接对表复制。

      Lua5.3参考文档对rawset的解释:

      Lua不允许值为nil的全局变量,因为值为nil的全局变量都会被自动地认为自己是未声明的。但是,要允许值为nil的全局变量也不难,只需要引入一个辅助表来保存已声明的名称即可。

 

 (二)非全局环境_ENV

         lua 5.2 正式发布了,对于 lua 语言本身的修改,重中之重就是对 environment 这个概念的修改,本质上,lua 取消了原有意义上的 environment,而是通过使用非全局变量_ENV(上值upvalue)来保存这个全局环境 。全局变量实际上只是一个语法糖,编译时再前面加上了 _ENV. 的前缀。这样,从 load 开始,第一个 chunk 就被加上了 _ENV 这个 upvalue ,然后依次传递下去。

       

        简单来说其实就是经历了这三个步骤

  1. 编译器在编译所有代码段之前,在外层创建局部变量_ENV
  2. 编译器将所有的自由名称var变换为_ENV.var
  3. 函数load使用全局环境(保存在_G)初始化代码段的第一个上值,即Lua语言内部维护的一个普通的表

       当我们声明一个"全局"变量时,其实是把这个变量声明到用全局环境初始化的上值_ENV中而已。当我们把_ENV置空之后就会丢失掉全局函数的环境。

       这么做的好处是什么呢

      在我看来,这就有点像C++中的命名空间,一方面能够保护_G这个全局环境不被污染,另一方面则是避免了同名函数发生覆盖的情况。

      如果想调用某模块的全局函数需要先引入该模块

 

      如果调用不同模块之间的同名函数,那么会调用最后require的模块函数

     最后,其实_ENV也不一定非要使用全局环境初始化,我们可以通过loadfile中的可选参数,给这个模块创立一个新的环境。这样做的好处是哪怕此时有恶意代码进入该模块,也无法访问到其他全局数据。

 

 

以上是学习路上的一点思绪,欢迎大家评论指点~

点赞,关注!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lampard杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值