1. --我们可以把环境看成一张存放全局变量的表
  2. --当前环境是_G
  3. global_var = "init" -- 类似_G[global_var] = "init"
  4. print(global_var) -- 类似_G[global_var]

动态名字访问全局变量

Lua在一系列的环境中保存全局变量。_G保存当前环境所有全局变量。

  1. for n in pairs(_G) do
  2. print(n) --当前环境的所有全局变量值
  3. end
  4. setGlobal("t.x.y", 10) -->设置全局变量
  5. print(t.x.y) --> 10
  6. print(getGloabl("t.x.y")) --> 10
  7. function getGlobal (f)
  8. local v = _G -- start with the table of globals
  9. for w in string.gfind(f, "[%w_]+") do
  10. v = v[w]
  11. end
  12. return v
  13. end
  14. function setGlobal (f, v)
  15. local t = _G -- start with the table of globals
  16. for w, d in string.gfind(f, "([%w_]+)(.?)") do
  17. if d == "." then -- not last field?
  18. t[w] = t[w] or {} -- create table if absent
  19. t = t[w] -- get the table
  20. else -- last field
  21. t[w] = v -- do the assignment
  22. end
  23. end
  24. end

全局变量管理

全局变量无需声明,规模大了,混乱。

  1. declare("x", 1)
  2. print(x) --> 1
  3. print(y) --> 报错:attempt to read undeclared var.
  4. local declaredNames = {}
  5. function declare (name, initval)
  6. rawset(_G, name, initval)
  7. declaredNames[name] = true
  8. end
  9. setmetatable(_G, {
  10. __newindex = function (t, n, v)
  11. if not declaredNames[n] then
  12. error("attempt to write to undeclared var. "..n, 2)
  13. else
  14. rawset(t, n, v) -- do the actual set
  15. end
  16. end,
  17. __index = function (_, n)
  18. if not declaredNames[n] then
  19. error("attempt to read undeclared var. "..n, 2)
  20. else
  21. return nil
  22. end
  23. end,
  24. })

自定义环境

setfenv:设置当前chunk的环境,环境可以看成是存储所有变量的全局表。

  1. --设置stacklvl级栈的活动函数的环境表
  2. --stacklvl: 栈级别,
  3. -- 1,当前坐在函数
  4. -- 2,调用当前函数的函数
  5. -- env_t: 新的环境表
  6. setfenv(stacklvl,env_table)
  7. a = 1 --当前环境_G
  8. setfenv(1, {_G = _G}) --当前环境:{_G = _G}
  9. a = 10
  10. _G.print(a) --> 10
  11. _G.print(_G.a) --> 1
  12. local newgt = {}
  13. setmetatable(newgt, {__index = _G})
  14. setfenv(1, newgt) --
  15. print(a) --> 1