请选择 进入手机版 | 继续访问电脑版
  • 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

Lua全局变量管理

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
 

  Lua全局变量不需要声明就可以使用。虽然这种特性在我们学习语言时很方便,但在项目中则可能因为一些手误漏掉local关键字而引起一些很难发现的BUG。现在的项目,为了方便热更新,大部分逻辑都采用lua来实现,所以在项目初期就对全局变量的进行了规范化的管理。

  首先,想要使用全局变量,必须先进行声明,才能使用。使用未声明的全局变量会报错,并定位到所在文件,所在行。具体实现方便如下,主要采用了lua的元表和元方法来实现。

 1 local _logerror = print
 2 
 3 local _global = {}
 4 
 5 local __global_mt = {
 6     __index = function(t, k)
 7         if not _global[k] then
 8             _logerror(debug.traceback("attempt to read an undeclared global variable :" .. k, 2))
 9         end
10 
11         return nil
12     end,
13 
14     __newindex = function(t, k, v)
15         if not _global[k] then
16             _logerror(debug.traceback("attempt to write an undeclared global variable : " .. k, 2))
17             return
18         end
19 
20         rawset(t, k, v)
21     end
22 }
23 
24 setmetatable(_G, __global_mt)

  测试代码如下:

1 require("global")
2 
3 test1 = 1
4 
5 print(test2)

  测试结果如下:

  [G] attempt to write an undeclared global variable : test1
  stack traceback:
  F:/workspace/LuaDemo/test.lua:3: in main chunk
  [C]: in ?
  [G] attempt to read an undeclared global variable :test2
  stack traceback:
  F:/workspace/LuaDemo/test.lua:5: in main chunk
  [C]: in ?
  nil

  要想使用全局变量必须使用使用特性的声明函数,这里主要是利用rawset,它可以绕过元方法:

local function _declare_global(k, v)
    if not rawget(_G, k) then
        rawset(_G, k, v or false)
    else
        _logerror(debug.traceback("variable was already declared: " .. k, 2))
        return nil
    end

    _global[k] = true
    return _G[k]
end

  为了项目的课阅读性,我们规定项目中所有全局变量命名必须是g_xxx的形式,增加了命名规则检测后,完整的global文件如下:

 1 local _logerror = print
 2 
 3 local _global = {}
 4 
 5 local __global_mt = {
 6     __index = function(t, k)
 7         if not _global[k] then
 8             _logerror(debug.traceback("attempt to read an undeclared global variable :" .. k, 2))
 9         end
10 
11         return nil
12     end,
13 
14     __newindex = function(t, k, v)
15         if not _global[k] then
16             _logerror(debug.traceback("attempt to write an undeclared global variable : " .. k, 2))
17             return
18         end
19 
20         rawset(t, k, v)
21     end
22 }
23 
24 setmetatable(_G, __global_mt)
25 
26 -- 全局变量命名规范(g_xxx)
27 local _naming_pattern = "g_"
28 
29 local function _declare_global(k, v)
30     if not rawget(_G, k) then
31         if k:sub(1, #_naming_pattern) ~= _naming_pattern then
32             _logerror("invalid naming: global variable name is g_xxx")
33         end
34 
35         rawset(_G, k, v or false)
36     else
37         _logerror(debug.traceback("variable was already declared: " .. k, 2))
38         return nil
39     end
40 
41     _global[k] = true
42     return _G[k]
43 end
44 
45 _declare_global("declare_G", _declare_global)

 

  所有全局变量声明格式(支持初始值为nil):

1 declare_G("g_test", 123)

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Lua C++交互 应用实例步骤(UserData使用)发布时间:2022-07-22
下一篇:
使用luastudio,调试 lua配置发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap