美文网首页
解决滥用lua全局变量

解决滥用lua全局变量

作者: 一枚64byte的仙女 | 来源:发表于2019-07-18 18:29 被阅读0次

    在开发过程中发现有滥用lua全局变量的情况,原因是Lua的全局变量不用显示声明就能使用,(比如:Util = LuaFramework.Util )

    解决问题:

    1.避免全局变量,不显式声明就使用的情况,即,常用模块的全局变量,只能在主模块进行显式声明后才能使用,在项目别的位置使用或定义未经声明的全局变量,则抛出错误。

    2.怎么避免重定义,从而覆盖了某全局变量的情况?

    比如:(Util = LuaFramework.LogUtil),也不会影响_G("Util")原有的定义。

    过程:在<Lua程序设计 第2版(中文版)>书中【14.2全局变量声明】和【14.3非全局环境】中已经对以上问题进行了探讨,具体的内容大家可以详细看看。

    解决方案:

    对于问题1:

    引用strict.lua ,他实现了对全局变量的检查,只允许全局变量先声明再使用。

    该代码的原理:

    1.设置_G的metatable来运行时检测(肯定不能静态检测),当我们对_G表进行更新或者赋值是会触发__newindex 和 __index 元方法,

    我们在这里进行约束:如果该变量从未显式的声明过,则抛出"assign to undeclared variable" 和 "variable n is not declared" 错误。

    2.如何判断某全局变量是否声明过:debug.getinfo是调试Lua程序时一个很重要很常见的函数,主要用于获取函数调用的基本信息。

    这个函数的难点在于各个参数的含义。

    具体用法,直接百度就可以了。这里用getinfo(2,"s")获取 fills in the fieldssource,linedefined,lastlinedefined,what, andshort_src;(source)strict.lua定义__declared = {} 存放已经声明过的变量,

    首先判断该变量是否存在__declared,如果不在再判断linedefined (函数定义的起始行号)是否大于0.,如果大于0则表示该变量未声明,反之则将该变量存入__declared 表.

    对于问题2:

    使用setfenv(f,table):设置一个函数的环境,关于具体的用法可以百度.

    注意:

    1.一旦改变了环境,所有的全局访问就都会使用新的table。如果新table是空的,

    那么就会丢失所有的全局变量,包括_G.所有应该先将一些有用的值录入其中

    2.使用继承组装新环境a = 1local newget = {}setmetatable(newgt,{__index = _G})setfenv(1,newgt)这段代码,

    新环境从原环境中继承了print和a,然而,任何赋值都发生在新的table中。若误改了一个全局变量也没什么,仍然能通过_G来修改全局变量.由于函数继承了创建其函数的环境.所以一个程序块若改变了它自己的环境,

    那么后续由它创建的函数都将共享这个新环境。

    修改思路:

    1.启动游戏,默认进行_G的沙盒环境。

    2.自定义每个子游戏的沙盒环境.Env_Game1.Init(--组安新环境)

    3.当子游戏模块载入成功后,触发回调Callback()调用setfenv(0,Env_Game1.GetEnv()):参数0,代表将当前环境切换为指定环境

    4.从子游戏退出至大厅时,切换沙盒环境为_G

    相关文章

      网友评论

          本文标题:解决滥用lua全局变量

          本文链接:https://www.haomeiwen.com/subject/inrrlctx.html