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