setmetatable(_G,{
__newindex = function(t,n,v)
local w = debug.getinfo(2,"S").what
if w ~= "main" and w ~= "C" then
error("attempt to write to undeclared variable"..n,2)
end
rawset(t,n,v)
end,
__index = function(_,n)
error("not exsits "..n,2)
end
})
a = 100
print(a)因为全局变量都是保存在一个_G的table中的,所以可以改变它的元方法达到限制新索引的添加
rawset和rawget方法可以跳过元表的元方法。
Lua的全局变量其实都是整合到一个加_G的table中的,在任何地方都可以修改和创建全局变量。这个非常方便,但是全局变量的修改就会影响到所有程序,还是小心为妙。
for n in pairs(_G) do print(n)--打印所有的全局变量 end
--2.lua function test(a,b) print(a+b) end
--3.lua
function testDo(a,b)
print(a+b)
end
print('DoFile')f = loadstring('print(123)')
f()
t = loadfile('2.lua') --只是编译
t() --先定义test方法
test(1,2) --3
d = dofile('3.lua') --DoFile,直接编译了,然后定义
testDo(5,3) --8
s = loadfile('5.lua')
print(s) --nil,dofile会发生错误在语言运行时,有能力且轻易的执行动态生成的代码,有了这些dofile等才可以将Lua称为一种解析型语言。
a = {"one","two","three"}
for i,v in pairs(a) do
print(i,v)
end
for i,v in next,a,nil do
print(i,v)
endpairs使用的迭代器是next(table,key),如果key值为nill就返回第一个值,如果是某一个key值(index下标的),就从它的下一个index开始。如果是一个keyName值,就会随机遍历整个table
a = {"one","two","three"}
for i,v in ipairs(a) do
print(i,v)
end
local function iter(a,i)
i = i+1
local v = a[i]
if v then
return i,v
end
end
function ipairss(a)
return iter,a,0
end
for i,v in ipairss(a) do
print(v) --和ipairs的输出一样
end可以看出,for使用迭代器,in需要获3个参数,迭代器函数、恒定状态、控制变量初始值
function newCounter() local i = 0 return function() i = i+1 return i end end c = newCounter() print(c()) --1 print(c()) --2 c2 = newCounter() print(c2()) --1 print(c()) --3 print(c2()) --2
在newCounter中返回了一个闭合函数,使用到了一个newCounter的局部变量i,但是返回的闭合函数使用的i是保留存在的
调用新的newCounter会产生一个新的i,值是独立的,看上面代码的输出。
function go(arg)
return realGO(arg.bdel,arg.del)
end
function realGO(bdel,del)
return bdel - del
end
local val = go({bdel=100,del=30})
print(val)这是一种技巧,将参数以table的形式传递,可以在任意位置指定某个参数的值,就不需要记住参数的排放位置了
也可以在伪调用的函数里做一些参数的验证和判断或则设置默认值。
function go(...)
for i,v in ipairs{...} do
print(v)
end
end
function goo(...)
for i=1,select('#',...) do
print(select(i,...))
end
end
go(5,nil,1) --5
goo(nil,1,5,9) --4行 nil,1,5,9 1,5,9 5,9 9变长参数只要只用...代表就可以了,...代表一个数组吧
使用ipairs访问变长数组会遇到nil值就停止,如果参数中存在nil,那么后面的值将无法访问
使用select可以访问包含nil值,select('#',...)表示取这个数组的长度,select(1,...)表示返回第一个及后面所有,select(2,...)表示返回第二个及后面所有......所以要获取具体第几位的参数值,只需要一个临时变量来去承接返回来的第一个值,其他舍弃调就行了。
t = {"nihao",fg="asd"}
t[10] = 'love'
print(unpack(t)) --nihao
print(t.fg) --asd
print(t[10]) --love
t[2] = 100
t[3] = nil
t[4] = 200
print(unpack(t)) --nihao 100 nil 200unpack函数会从table的下标1开始,一直往上递增,直到遇到nil索引为止
function f1()
return 1
end
function f2()
return 1,2
end
t = {f1(),f2()}
print(unpack(t)) --1,1,2
t2 = {f1(),f2(),5}
print(unpack(t2)) --1,1,5
t3 = {f1(),f2(),f2(),f2()}
print(unpack(t3)) --1,1,1,1,2可以看出当用function的返回值来构造table时,table前面function只会用到第一个返回值,之后table最后一个元素且是函数的函数会返回所有的返回值