LUA中關於全域變數環境是本文要介紹的內容,主要輸來瞭解並學習全域變數的環境,具體內容先來看本文詳解。
一、全域變數的環境
LUA在全域變數的實現方式上用了一個絕對讓我們喜聞樂見的做法,複用已有的table機制,將全域變數都儲存在_G表中。這樣做好處很多。
從語言實現角度來說,不需要為了全域變數單獨去做一份實現,只要複用下table機制即可。
從使用角度來說,雖然你是全域變數看起來較為牛逼local變數內牛滿面的蹲在一邊哭)一點,但是你也不幸的被放在了table中。於是所有針對一個table可以做的事情針對全域量一樣可以做:
1、變數動態名稱訪問: 運行期才知道那全域量叫啥,訪問起來吃力。現在好了,因為放在了table中,所以只要寫上 _G[varname] 就可以訪問了,寫上 _G[varname]=ABC就可以賦值了。不用再去靠拼接字串來chunk代碼了。
2、metatable可以使用。雖然又提到了metatable,不用說這裡指代的是table禦用__index和__newindex運算子。通過實現這兩個運算子,我們可以對全域變數_G表做許多的事情,其中最常見的就是,通過重新實現__index和__newindex來為LUA中的全域變數使用規則進行修改,加上強型別語言中的“先聲明後使用,不聲明不能用”的規則。這點在手冊上有詳細的描述不再COPY。
二、全域變數的局部環境
在C++中變數的範圍是從內向外尋找,並且具備遮蔽效果。在lua中全域變數方面,有一個特點很有意思,就是允許每一個函數具有自己的局部“全域環境”,聽著衝突其實不然。“局部”意指函數的內部,“全域環境”就是指全域變數儲存的_G表。也就是說LUA允許每一個函數內部使用一個私人的_G表,在文章中,這被稱作是函數的環境。setfenv()可以更改一個指定函數的環境,第一個參數為函數名,第二個參數為這個函數的私人_G名,可以先初始化好再傳遞過去。第一個參數也可以是一個數字,1表示當前正在執行的這個函數,2表示當前函數的調用者,3表示調用者的調用者其實這個數字是棧頂的活動函數調用層次)。
不過要注意一點,調用setfenv()設定了私人_G表後,原來的_G表預設就不可訪問了,這個時候很多原來_G中的函數你都無法使用,比如print。因此你可以或者在私人_G表中儲存原始_G表,或者為私人_G表設定__index操作符指向原始_G表,相比來說我更喜歡後者,優雅且省事懶%……)。
ps, 感慨下,table是LUA中的唯一複雜結構,所有複雜的資料結構和描述都要基於此。__index和__newindex是table非常重要的兩個metatable運算子沒有之一。
小結:LUA中關於全域變數環境學習教程的內容介紹完了,希望通過本文的學習能對你有所協助!