lua学习之全局变量,lua全局变量


全局变量保存在_G表中。

全局变量不需要声明,对小的程序很方便。当程序很大时,可能会导致很难发现的bug.

方法1:

function declare(name, initval )
	rawset(_G, name, initval or false)   --rawset是会绕过metamethod的
end
setmetatable(_G, {

	__newindex = function (_, n)
		error("attempt to write to undeclared variable "..n,2)
	end,

	__index = function (_, n)
		error("attempt to read undeclared variable "..n,2)
	end,
})

--测试
declare("a")
a = 1
print(a)

方法2:允许全局变量可以为nil

local declareNames = {}
function declare(name, initval)
	rawset(_G, name, initval)
	declareNames[name] = true
end

setmetatable(_G, {

	__newindex = function(t, n, v)
		if not declareNames[n] then
			error("attempt to write to undeclared var."..n,2)
		else
			rawset(t, n, v)
		end
	end,

    __index  = function (_, n)
    	print("attempt to read n")
    	if not declareNames[n] then
    		error("attempt to read undeclared var."..n,2)
    	else
    		return nil
    	end
    end, 	
	})
--测试
declare "a"
a=1
print(a)

非全局环境:

当安装metatable去控制全局访问时,你的整个程序都会受影响。 LUA5.0 允许每个函数有自己的环境。使用setfenv,接受函数和新的环境为参数,还可以使用数字表示栈顶活动的函数,数字1表示当前的函数,数字2表示调用当前函数的函数。

local newgt = {}  --create new environment
setmetatable(newgt, {__index = _G})
setfenv(1, newgt)
declare "a"
a = 1
print(_G.a)    --输出为nil
print(newgt.a) --输出为1
这段代码继承了旧环境的print. a是新环境下的全局变量。任何赋值操作是对新表进行,不用担心误操作修改了全局变量表_G. 不过你仍然可以通过_G修改全局变量。 例如:_G.c=10

相关内容

    暂无相关文章