LUA中關(guān)于全局變量環(huán)境學(xué)習(xí)教程
LUA中關(guān)于全局變量環(huán)境是本文要介紹的內(nèi)容,主要輸來(lái)了解并學(xué)習(xí)全局變量的環(huán)境,具體內(nèi)容先來(lái)看本文詳解。
一、全局變量的環(huán)境
LUA在全局變量的實(shí)現(xiàn)方式上用了一個(gè)絕對(duì)讓我們喜聞樂(lè)見(jiàn)的做法,復(fù)用已有的table機(jī)制,將全局變量都保存在_G表中。這樣做好處很多。
從語(yǔ)言實(shí)現(xiàn)角度來(lái)說(shuō),不需要為了全局變量單獨(dú)去做一份實(shí)現(xiàn),只要復(fù)用下table機(jī)制即可。
從使用角度來(lái)說(shuō),雖然你是全局變量看起來(lái)較為牛逼(local變量?jī)?nèi)牛滿面的蹲在一邊哭)一點(diǎn),但是你也不幸的被放在了table中。于是所有針對(duì)一個(gè)table可以做的事情針對(duì)全局量一樣可以做:
1、變量動(dòng)態(tài)名稱訪問(wèn): 運(yùn)行期才知道那全局量叫啥,訪問(wèn)起來(lái)吃力?,F(xiàn)在好了,因?yàn)榉旁诹藅able中,所以只要寫(xiě)上 _G[varname] 就可以訪問(wèn)了,寫(xiě)上 _G[varname]=ABC就可以賦值了。不用再去靠拼接字符串來(lái)chunk代碼了。
2、metatable可以使用。雖然又提到了metatable,不用說(shuō)這里指代的是table御用__index和__newindex運(yùn)算符。通過(guò)實(shí)現(xiàn)這兩個(gè)運(yùn)算符,我們可以對(duì)全局變量_G表做許多的事情,其中最常見(jiàn)的就是,通過(guò)重新實(shí)現(xiàn)__index和__newindex來(lái)為L(zhǎng)UA中的全局變量使用規(guī)則進(jìn)行修改,加上強(qiáng)類(lèi)型語(yǔ)言中的“先聲明后使用,不聲明不能用”的規(guī)則。這點(diǎn)在手冊(cè)上有詳細(xì)的描述不再COPY。
二、全局變量的局部環(huán)境
在C++中變量的作用域是從內(nèi)向外查找,并且具備遮蔽效果。在lua中全局變量方面,有一個(gè)特點(diǎn)很有意思,就是允許每一個(gè)函數(shù)具有自己的局部“全局環(huán)境”,聽(tīng)著沖突其實(shí)不然。“局部”意指函數(shù)的內(nèi)部,“全局環(huán)境”就是指全局變量保存的_G表。也就是說(shuō)LUA允許每一個(gè)函數(shù)內(nèi)部使用一個(gè)私有的_G表,在文章中,這被稱作是函數(shù)的環(huán)境。setfenv()可以更改一個(gè)指定函數(shù)的環(huán)境,***個(gè)參數(shù)為函數(shù)名,第二個(gè)參數(shù)為這個(gè)函數(shù)的私有_G名,可以先初始化好再傳遞過(guò)去。***個(gè)參數(shù)也可以是一個(gè)數(shù)字,1表示當(dāng)前正在執(zhí)行的這個(gè)函數(shù),2表示當(dāng)前函數(shù)的調(diào)用者,3表示調(diào)用者的調(diào)用者(其實(shí)這個(gè)數(shù)字是棧頂?shù)幕顒?dòng)函數(shù)調(diào)用層次)。
不過(guò)要注意一點(diǎn),調(diào)用setfenv()設(shè)置了私有_G表后,原來(lái)的_G表默認(rèn)就不可訪問(wèn)了,這個(gè)時(shí)候很多原來(lái)_G中的函數(shù)你都無(wú)法使用,比如print。因此你可以或者在私有_G表中保存原始_G表,或者為私有_G表設(shè)置__index操作符指向原始_G表,相比來(lái)說(shuō)我更喜歡后者,優(yōu)雅且省事(懶%……)。
ps, 感慨下,table是LUA中的***復(fù)雜結(jié)構(gòu),所有復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和描述都要基于此。__index和__newindex是table非常重要的兩個(gè)metatable運(yùn)算符沒(méi)有之一。
小結(jié):LUA中關(guān)于全局變量環(huán)境學(xué)習(xí)教程的內(nèi)容介紹完了,希望通過(guò)本文的學(xué)習(xí)能對(duì)你有所幫助!