天天看點

lua程式設計 全局變量 環境 子產品

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就不是這個子產品名了)