--我们可以把环境看成一张存放全局变量的表--当前环境是_Gglobal_var = "init" -- 类似_G[global_var] = "init"print(global_var) -- 类似_G[global_var]
动态名字访问全局变量
Lua在一系列的环境中保存全局变量。_G保存当前环境所有全局变量。
for n in pairs(_G) doprint(n) --当前环境的所有全局变量值endsetGlobal("t.x.y", 10) -->设置全局变量print(t.x.y) --> 10print(getGloabl("t.x.y")) --> 10function getGlobal (f)local v = _G -- start with the table of globalsfor w in string.gfind(f, "[%w_]+") dov = v[w]endreturn vendfunction setGlobal (f, v)local t = _G -- start with the table of globalsfor w, d in string.gfind(f, "([%w_]+)(.?)") doif d == "." then -- not last field?t[w] = t[w] or {} -- create table if absentt = t[w] -- get the tableelse -- last fieldt[w] = v -- do the assignmentendendend
全局变量管理
全局变量无需声明,规模大了,混乱。
declare("x", 1)print(x) --> 1print(y) --> 报错:attempt to read undeclared var.local declaredNames = {}function declare (name, initval)rawset(_G, name, initval)declaredNames[name] = trueendsetmetatable(_G, {__newindex = function (t, n, v)if not declaredNames[n] thenerror("attempt to write to undeclared var. "..n, 2)elserawset(t, n, v) -- do the actual setendend,__index = function (_, n)if not declaredNames[n] thenerror("attempt to read undeclared var. "..n, 2)elsereturn nilendend,})
自定义环境
setfenv:设置当前chunk的环境,环境可以看成是存储所有变量的全局表。
--设置stacklvl级栈的活动函数的环境表--stacklvl: 栈级别,-- 1,当前坐在函数-- 2,调用当前函数的函数-- env_t: 新的环境表setfenv(stacklvl,env_table)a = 1 --当前环境_Gsetfenv(1, {_G = _G}) --当前环境:{_G = _G}a = 10_G.print(a) --> 10_G.print(_G.a) --> 1local newgt = {}setmetatable(newgt, {__index = _G})setfenv(1, newgt) --print(a) --> 1
