1. 程式人生 > >lua程式設計 全域性變數 環境 模組

lua程式設計 全域性變數 環境 模組

1.全域性變數與環境

lua中真正儲存全域性變數的地方不是在_G裡面,而是在setfenv(i,table)的table中,所有當前的全域性變數都在這裡面找,只不過在程式開始時lua會預設先設定一個變數

_G=這個裡面的table而已。所以在新設定環境後,如果還想找到之前的全域性變數,通常需要附加上為新的table設定元表{_index=_G}

下面的幾個例子:

a=1
print(a)
print(_G.a)
--正常情況,輸出1,1

a=1
setfenv(1,{})
print(a)
print(_G.a)
--這時會出錯說找不到print,因為當前的全域性變量表示空的,啥也找不到的

a=1
setfenv(1,{_G=_G})
_G.print(_G.a)

print(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(a)
print(_G.a)

--這是正確輸出,因為新的全域性表採用之前的表做找不到時的索引,原先的表裡面存在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就不是這個模組名了)

本文出自:http://blog.csdn.net/leonwei/article/details/7739930