當我拿到_env表的時候,會去想這個_env表是幹什麼用的? 首先看如下**:
1viewcodeprint(_env) --
0x1d005f0
2print(_g) --
0x1d005f0
看了上面的**,就感覺_env表不就是_g表嗎?但_env表是不是全域性的呢?我又列印了_g表的內容:
1view codefor k , v in
pairs(_g) do
2print
(k , v)
3end
4--[[
5package table: 0xad1e50
6setmetatable function: 0x419220
7pairs function: 0x419380
8require function: 0xad3900
9loadfile function: 0x419540
10print function: 0x418ce0
11module function: 0xad3890
12rawlen function: 0x418c50
13load function: 0x419430
14getmetatable function: 0x4195b0
15type function: 0x418800
16coroutine table: 0xad3970
17table table: 0xad3d10
18error function: 0x418f40
19_version lua 5.2
20debug table: 0xad4bb0
21string table: 0xad2700
22rawequal function: 0x418ca0
23math table: 0xad64d0
24tonumber function: 0x418870
25bit32 table: 0xad2d60
26os table: 0xad3c60
27loadstring function: 0x419430
28pcall function: 0x4191c0
29io table: 0xad4030
30select function: 0x418aa0
31unpack function: 0x41fb40
32collectgarbage function: 0x418fb0
33xpcall function: 0x419110
34rawset function: 0x418bb0
35ipairs function: 0x4193a0
36next function: 0x418e20
37rawget function: 0x418c00
38tostring function: 0x418840
39arg table: 0xad76a0
40_g table: 0xad15f0
41assert function: 0x419680
42dofile function: 0x419600
43]]
發現_g表中的key是沒有_env表的,就比較疑惑?那_env到是什麼,是怎麼樣產生的?關於這兩個問題我看了lua閉包
的原始碼,lua閉包有兩種生成方式,其中一種是在lua原始碼載入時,會生成閉包(ps:關於閉包的整體內容會在之後的另一篇部落格講),
對於該閉包它的第乙個upvalue就是_env,具體**如下:
1 lua_api int lua_load (lua_state *l, lua_reader reader, void *data,lua_load中將登錄檔中的全域性表(_g賦值給_env)2 const char *chunkname, const char *mode) 19}
20lua_unlock(l);
21return
status;
22 }
所以_env缺省會指向_g表。至於_g表是如何建立的,各位可以參考這個部落格。那_env表的作用是什麼呢?
_env表的作用:表示當前**塊的環境,每乙個**塊的環境都有一張_env。關於**塊的解釋可以看這裡。我們可以看一下下面這段**就理解了:
1view codefunction
foorbar(env)
2local
_env =env
3return
function() print("
yes") end
4end56
print(_env)7
8local l_test =foorbar({})910
(l_test())
1112
--[[
13table: 0x1a395f0
14lua: code:3: attempt to call global 'print' (a nil value)
15stack traceback:
16code:3: in function 'l_test'
17code:10: in main chunk
18[c]: in ?
19]]
上述可以看出,我們的所有內部函式都定義與一張_env表中,比如在print時實際上是_env.print(語法糖省略了),所以在**塊foorbar中_env被賦值為{},所以print就訪問不到了。
所以_env表的作用實際上是充當環境,所以在5.2之後就沒有全域性變數這樣乙個說法(_env = _g還是有全域性變數的)。這種做法類似於5.1的setfenv。關於如何實現setfenv在雲風的部落格有提及。
lua5 2 帶你理解 ENV和 G
5.1之前,全域性變數儲存在 g這個table中,這樣的操作 a 1 相當於 g a 1 但在5.2之後,引入了 env叫做環境,與 g全域性變數表產生了一些混淆,需要從原理上做乙個理解。在5.2中,操作a 1 相當於 env a 1 這是乙個最基礎的認知改變,其次要格外注意 env不是全域性變數,...
lua元表理解
2015 08 23 22 13 237人閱讀收藏 舉報 lua 在lua中任何變數都有乙個元表 我相信每個字串元表都是string相關,所以可以使用string length 元表中特殊的值有特殊的含義,比如 index,call,add等等。函式setmetatable a,meta 就是將me...
LUA表的引用理解
lua中引用型別都是分配在堆上的 因此,我們在使用lua的table時,可盡可能的使用表的引用,而不需要拷貝表裡的元素 比如,通過rpc協議傳來乙個表a,我們想要快取這個表,只需要儲存該錶的引用 而不需要再重新生成乙個新錶然後將表a的元素乙個個拷過來 function func local t 生成...