1.全局變量與環境
lua中真正存儲全局變量的地方不是在_g裡面,而是在setfenv(i,table)的table中,所有目前的全局變量都在這裡面找,隻不過在程式開始時lua會預設先設定一個變量
_g=這個裡面的table而已。是以在新設定環境後,如果還想找到之前的全局變量,通常需要附加上為新的table設定元表{_index=_g}
下面的幾個例子:
a=1
print(a)
print(_g.a)
--正常情況,輸出1,1
setfenv(1,{})
--這時會出錯說找不到print,因為目前的全局變量表示空的,啥也找不到的
setfenv(1,{_g=_g})
_g.print(_g.a)
--這時_g.print(_g.a)可以正常嗎,因為可以在新的table中找到一個叫_g的表,這個_g有之前的奈爾全局變量,但是下面的print(a)則找不到print,因為目前的table{_g=_g}沒有一個叫print的東西
local mt={__index=_g}
local t={}
setmetatable(t,mt)
setfenv(1,t)
--這是正确輸出,因為新的全局表采用之前的表做找不到時的索引,原先的表裡面存在print 、_g、 a這些東西
setfenv的第一個參數可以是目前的堆棧層次,如1代表目前代碼塊,2表調用目前的上一層,也可以是具體的那個函數名,表示在那個函數裡。
每個新建立的函數都将繼承建立它的那個函數的全局環境
2.require
require的意義就是導入一堆可用的名稱,這些名稱(非local的)都包含在一個table中,這個table再被包含在目前的全局表(“通常的那個_g”)中,這樣通路一個子產品中的變量就可以使用_g.table.**了,(剛開始學習lua時還以為子產品裡的名稱在導入後直接就是在_g中的)
a=require("")的a取決于這個導入的檔案的傳回值,沒有傳回值時true,是以在标準的情況下子產品的結尾應該return這個子產品的名字,這樣a就是這個子產品的table了(當然不這樣做也ok,隻是a就不是這個子產品名了)