欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Lua中的全局變量、非全局變量總結(jié)

 更新時(shí)間:2014年09月29日 10:48:25   作者:果凍想  
這篇文章主要介紹了Lua中的全局變量、非全局變量總結(jié),全局變量可稱之為L(zhǎng)ua環(huán)境變量,需要的朋友可以參考下

前言

Lua將其所有的全局變量保存在一個(gè)常規(guī)的table中,這個(gè)table稱為“環(huán)境”。這種組織結(jié)構(gòu)的優(yōu)點(diǎn)在于,其一,不需要再為全局變量創(chuàng)造一種新的數(shù)據(jù)結(jié)構(gòu),因此簡(jiǎn)化了Lua的內(nèi)部實(shí)現(xiàn);另一個(gè)優(yōu)點(diǎn)是,可以像其他table一樣操作這個(gè)table。為了便于實(shí)施這種操作,Lua將環(huán)境table自身保存在一個(gè)全局變量_G中。例如,我們可以使用以下代碼打印當(dāng)前環(huán)境中所有全局變量的名稱。

復(fù)制代碼 代碼如下:

for n in pairs(_G) do print(n) end

在你的電腦上運(yùn)行一下以上代碼,看看結(jié)果。

全局變量聲明

在Lua中,全局變量不需要聲明就可以直接使用,但是這樣違反了編程的大忌,隨便使用全局變量,將導(dǎo)致程序的性能,當(dāng)出現(xiàn)bug時(shí),也很難去發(fā)現(xiàn),同時(shí)也污染了程序中的命名??紤]到全局變量也是存放在一個(gè)table中,我們則可以通過元表來改變其它代碼訪問全局變量時(shí)的行為,看到了么?又是元表。代碼如下:

復(fù)制代碼 代碼如下:

setmetatable(_G, {
     __newindex = function (_, k)
          error("Attempt to write to undeclared variable " .. k)
     end,
     __index = function (_, k)
          error("Attempt to read undeclared variable " .. k)
     end
})
 
print(a) -- 這里a就是一個(gè)全局變量

而有的時(shí)候,我們的確需要定義一個(gè)全局變量,那怎么辦?還記得我在《Lua中的元表與元方法》這篇文章中寫的嗎?使用rawset就可以完成,它是不同過元表的,直接設(shè)置table的值;同時(shí),為了測(cè)試一個(gè)變量是否存在,就不能簡(jiǎn)單的將它與nil比較。因?yàn)槿绻鼮閚il,訪問就會(huì)拋出一個(gè)錯(cuò)誤,同樣,我們可以使用rawget來繞過元方法。

非全局的變量

由于“環(huán)境”這個(gè)概念是全局的,任何對(duì)他的修改都會(huì)影響程序的所有部分。例如:若安裝一個(gè)元表用于控制全局變量的訪問,那么整個(gè)程序都必須遵循這個(gè)規(guī)范。但使用某個(gè)庫(kù)時(shí),沒有先聲明就使用了全局變量,那么這個(gè)程序就無法運(yùn)行了。

可以通過函數(shù)setfenv來改變一個(gè)函數(shù)的環(huán)境。該函數(shù)的參數(shù)是一個(gè)函數(shù)和一個(gè)新的環(huán)境table。第一個(gè)參數(shù)除了可以指定為函數(shù)本身,還可以指定為一個(gè)數(shù)字,以表示當(dāng)前函數(shù)調(diào)用棧中的層數(shù)。數(shù)字1表示當(dāng)前函數(shù),數(shù)字2表示調(diào)用當(dāng)前函數(shù)的函數(shù),以此類推。首先來一小段代碼:

復(fù)制代碼 代碼如下:

a = 1 -- 這里創(chuàng)建了一個(gè)全局變量
 
-- 將當(dāng)前環(huán)境變量改為一個(gè)新的空table
setfenv(1, {})
print(a)

運(yùn)行代碼會(huì)彈出這樣的錯(cuò)誤:attempt to call global ‘print' (a nil value)

print是存放在_G中的,由于我們將當(dāng)前的環(huán)境變量重置為了一個(gè)空的table,導(dǎo)致找不到print了,所以就出現(xiàn)了錯(cuò)誤。為了防止這樣的錯(cuò)誤的放生,在我們改變當(dāng)前的環(huán)境變量之前,我們需要保存當(dāng)前的環(huán)境變量??聪旅娴拇a:

復(fù)制代碼 代碼如下:

a = 1 -- 這里創(chuàng)建了一個(gè)全局變量
 
-- 將當(dāng)前環(huán)境變量改為一個(gè)新的空table
setfenv(1, {g = _G})
g.print(a)          -- 輸出nil
g.print(g.a)     -- 輸出1

這個(gè)時(shí)候訪問g就會(huì)得到原來的環(huán)境,這個(gè)環(huán)境中包含了字段print。我們可以使用名字_G來代替g,如下述代碼:
復(fù)制代碼 代碼如下:

a = 1 -- 這里創(chuàng)建了一個(gè)全局變量
 
-- 將當(dāng)前環(huán)境變量改為一個(gè)新的空table
setfenv(1, {_G = _G})
_G.print(a)          -- 輸出nil
_G.print(_G.a)     -- 輸出1

不要忘了我們之前總結(jié)的__index元方法,我們可以設(shè)置新的環(huán)境變量的__index為_G,這樣,當(dāng)在新的環(huán)境中找不到對(duì)應(yīng)的變量時(shí),就會(huì)去_G中找,這樣,就相當(dāng)于新的環(huán)境變量繼承了全局的環(huán)境變量_G,看以下代碼:

復(fù)制代碼 代碼如下:

a = 1 -- 這里創(chuàng)建了一個(gè)全局變量
 
local newEnv = {}
setmetatable(newEnv, {__index = _G})
 
-- 將當(dāng)前環(huán)境變量改為一個(gè)新的空table
setfenv(1, newEnv)
print(a)

在Lua中,函數(shù)會(huì)繼承創(chuàng)建其的環(huán)境,所以一個(gè)程序塊若改變了它自己的環(huán)境,那么后續(xù)由它創(chuàng)建的函數(shù)都將共享這個(gè)新環(huán)境。這項(xiàng)機(jī)制對(duì)于創(chuàng)建名稱空間是很有用的。之后的總結(jié)中還會(huì)繼續(xù)講解的。

相關(guān)文章

  • Lua中的閉包學(xué)習(xí)筆記

    Lua中的閉包學(xué)習(xí)筆記

    這篇文章主要介紹了Lua中的閉包學(xué)習(xí)筆記,閉包是可以包含自由(未綁定到特定對(duì)象)變量的代碼塊;這些變量不是在這個(gè)代碼塊內(nèi)或者任何全局上下文中定義的,而是在定義代碼塊的環(huán)境中定義(局部變量),需要的朋友可以參考下
    2014-12-12
  • Lua教程(二十):Lua調(diào)用C函數(shù)

    Lua教程(二十):Lua調(diào)用C函數(shù)

    這篇文章主要介紹了Lua教程(二十):Lua調(diào)用C函數(shù),本文講解了C函數(shù)作為應(yīng)用程序的一部分、C函數(shù)庫(kù)成為L(zhǎng)ua的模塊等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • Lua中的操作符和表達(dá)式總結(jié)

    Lua中的操作符和表達(dá)式總結(jié)

    這篇文章主要介紹了Lua中的操作符和表達(dá)式總結(jié),本文總結(jié)了算術(shù)操作符、關(guān)系操作符、邏輯操作符、字符串連接、table構(gòu)造式等,需要的朋友可以參考下
    2014-09-09
  • Lua學(xué)習(xí)筆記之運(yùn)算符和表達(dá)式

    Lua學(xué)習(xí)筆記之運(yùn)算符和表達(dá)式

    這篇文章主要介紹了Lua學(xué)習(xí)筆記之運(yùn)算符和表達(dá)式,本文在代碼中使用注釋對(duì)Lua的運(yùn)算符和表達(dá)式做了講解,需要的朋友可以參考下
    2014-09-09
  • Lua性能優(yōu)化技巧(一):前言

    Lua性能優(yōu)化技巧(一):前言

    這篇文章主要介紹了Lua性能優(yōu)化技巧(一):前言,本文講解了2條優(yōu)化原則,本文是系列文章的第一篇,需要的朋友可以參考下
    2015-04-04
  • lua開發(fā)中實(shí)現(xiàn)MVC框架的簡(jiǎn)單應(yīng)用

    lua開發(fā)中實(shí)現(xiàn)MVC框架的簡(jiǎn)單應(yīng)用

    最近的游戲項(xiàng)目中使用了lua腳本來開發(fā),項(xiàng)目中用到了MVC框架,最近有朋友問我怎么弄,在這里簡(jiǎn)單分享一下思路和一些開發(fā)中的技巧。有需要的小伙伴可以參考下。
    2015-04-04
  • Lua教程(三):C語言、C++中調(diào)用Lua的Table示例

    Lua教程(三):C語言、C++中調(diào)用Lua的Table示例

    這篇文章主要介紹了Lua教程(三):C語言、C++中調(diào)用Lua的Table示例,即在C語言、C++中讀取、操作Lua的Table,需要的朋友可以參考下
    2014-09-09
  • Lua實(shí)現(xiàn)正序和倒序的文件讀取方法

    Lua實(shí)現(xiàn)正序和倒序的文件讀取方法

    這篇文章主要介紹了Lua實(shí)現(xiàn)正序和倒序的文件讀取方法,本文講解使用table生成鏈表完成正序和倒序的文件讀入功能,需要的朋友可以參考下
    2015-04-04
  • lua閉包的理解以及表與函數(shù)的幾種表達(dá)方法

    lua閉包的理解以及表與函數(shù)的幾種表達(dá)方法

    本文首先通過具體的例子講解了Lua中閉包的概念,然后總結(jié)了閉包的應(yīng)用場(chǎng)合,最后探討了Lua中閉包的實(shí)現(xiàn)原理,以及l(fā)ua中表與函數(shù)的3種表達(dá)方式的匯總
    2015-08-08
  • Lua函數(shù)用法研究

    Lua函數(shù)用法研究

    這篇文章主要介紹了Lua函數(shù)用法研究,本文講解了函數(shù)、變量的用法、返回多個(gè)結(jié)果值和可變參數(shù)等特性的示例,需要的朋友可以參考下
    2015-07-07

最新評(píng)論