ngin Finding Everything About Nginx Here

lua作用域本质

发表于 2015-06-19 阅读数 2938

lua没有全局变量,为什么这样设计呢?


以这个文件为例说明 test.lua

-------------------------------------

a = 100;

local m = 4;


function foo()

local i = 5;

print(a, m, i);


function bar()

print(a, m, i);

end

end


首先整个文件是个函数,它本身有个默认的变量G(upval类型)。任何函数里面都可以再定义函数,变量会往最外层找它的出处,如果没有,则变成G['varname']。

所以以上的变量会是这样的:

对文件这个函数,有3个变量a, m, foo,函数名本身也是。

a => G['a'];

m => local;

foo => G['foo'];


对foo这个函数,有4个变量i, print, a, m, bar。

i => local

print => G['print'];

m => upval

bar => G['bar']


对bar这个函数,有4个变量print, a, m, i。

print => G['print'];

a => G['a'];

m => upval;

i => upval;


我们解释下什么是local和upval。

local是已经声明为local的局部变量,lua变量跟js有点类似,除非显示声明为局部变量,否则是其它类型。local这样很好理解。

upval是在本函数里没有声明,但是在外层有声明的变量。简单讲就是在外层是local,或已经是upval的,属于本层函数的变量,如foo里的m,bar里的i。

G本身已经是个upval,它的值是一个lua里面的hash table。


现在我们知道lua有两种类型了:local和upval。那如果加上数组后会怎么样呢? 比如上面的foo函数,m是upval,那么m['k']则是tabup。i是local,那么i['k']则是table。因此lua总共就4种类型 local, upval, table, tabup。因此任何看似全局变量的,其实是tabup,也就是G['var']。lua就是这样通过抽象把全局变量给抹掉了。