對lua中 ENV表的理解 lua5 2版本以後

2022-08-11 18:18:10 字數 3074 閱讀 5516

當我拿到_env表的時候,會去想這個_env表是幹什麼用的? 首先看如下**:

1

print(_env) --

0x1d005f0

2print(_g) --

0x1d005f0

viewcode

看了上面的**,就感覺_env表不就是_g表嗎?但_env表是不是全域性的呢?我又列印了_g表的內容:

1

for 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]]

view code

發現_g表中的key是沒有_env表的,就比較疑惑?那_env到是什麼,是怎麼樣產生的?關於這兩個問題我看了lua閉包

的原始碼,lua閉包有兩種生成方式,其中一種是在lua原始碼載入時,會生成閉包(ps:關於閉包的整體內容會在之後的另一篇部落格講),

對於該閉包它的第乙個upvalue就是_env,具體**如下:

1 lua_api int lua_load (lua_state *l, lua_reader reader, void *data,

2 const char *chunkname, const char *mode) 19}

20lua_unlock(l);

21return

status;

22 }

lua_load中將登錄檔中的全域性表(_g賦值給_env)

所以_env缺省會指向_g表。至於_g表是如何建立的,各位可以參考這個部落格。那_env表的作用是什麼呢?

_env表的作用:表示當前**塊的環境,每乙個**塊的環境都有一張_env。關於**塊的解釋可以看這裡。我們可以看一下下面這段**就理解了:

1

function

foorbar(env)

2local

_env =env

3return

function() print("

yes") end

4end56

print(_env)7

8local l_test =foorbar({})910

print

(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]]

view code

上述可以看出,我們的所有內部函式都定義與一張_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 生成...