Lua中的函数环境、_G及_ENV
lua5.1中的全局環(huán)境變量
Lua將環(huán)境table保存在一個全局變量_G中,可以對其訪問和設置。一般我們把需要被訪問的對象和函數(shù)等放到這里,
然后我們可以在需要時通過它來訪問和使用。
可以通過value = _G["varname"]或者value = _G.varname來獲得動態(tài)名字的全局變量。
“環(huán)境”是全局的,任何對它的修改都會影響程序的所有部分。對簡單的使用不會有什么問題,但較復雜的應用,這個會是一大潛在的問題
Lua5.1中改變環(huán)境 - setfenv
Lua5.1允許每個函數(shù)擁有一個子集的環(huán)境來查找全局變量,可以通過setfenv來改變一個函數(shù)的環(huán)境,
第一個參數(shù)若是1則表示當前函數(shù),2則表示調用當前函數(shù)的函數(shù)(依次類推),第二個參數(shù)是一個新的環(huán)境table。
比如下面,修改了函數(shù)的環(huán)境, print不存在了,再訪問就會出錯。
va = 1 setfenv(1, {}) print(va) -- 會報錯,print是一個nil。這是因為一旦改變環(huán)境,所有的全局訪問都會使用新的table為了避免上述問題,可以使用
setfenv(1, {_G = _G})將原來的環(huán)境保存起來,然后用_G.print來引用。
另一種組裝新環(huán)境的方法是使用繼承,下面的代碼新環(huán)境從源環(huán)境中繼承了print和a,任何賦值都發(fā)生在新的table中。
a = 1 local newgt = {} setmetatable(newgt, {__index = _G}) setfenv(1, newgt) print(a)或者
a = 1 local newgt = {} setmetatable(newgt, {__index = _G})示例:
a = "1" -- create a global variable print(a, getmetatable(a)) local t ={} setmetatable(t, {__index = _G}) setfenv(1, t) -- 設置當前的func-env為t print(a)---- _G.print("_G:", a) -- _G: 1 t.print("t: ", a) -- t: 1setfenv(a, {}) -- change current environment to a new empty table print(a) -- attempt to call global 'print' (a nil value)Lua5.1之后的環(huán)境
在5.2之后, 引入了_ENV叫做環(huán)境,與_G全局變量表產(chǎn)生了一些混淆。
在5.2中, 操作a = 1相當于_ENV['a'] = 1
這是一個最基礎的認知改變,其次要格外注意_ENV不是全局變量,而是一個upvalue(非局部變量)。
其次,_ENV[‘_G’]指向了_ENV自身,這一目的是為了兼容5.1之前的版本,因為之前你也許會用到:
_G['a'] = 2, 在5.2中, 這相當于_ENV[‘_G’][‘a(chǎn)’],為了避免5.1之前的老代碼在5.2中運行錯誤,所以5.2設置了_ENV[‘_G’]=_ENV來兼容這個問題。然而你不要忘記_ENV[‘_G’]=_ENV,所以一切都順理成章了。
在5.1中,我們可以為一段代碼塊(或者函數(shù))設置環(huán)境,使用函數(shù)setfenv,這樣會導致那一段代碼/數(shù)訪問全局變量的時候使用了setfuncs指定的table,而不是全局的_G。
在5.2中,setfenv遭到了廢棄,因為引入了_ENV。 通過在函數(shù)定義前覆蓋_ENV變量即可為函數(shù)定義設置一個全新的環(huán)境,比如:
a = 3 function echo()local _ENV={print=print, a = 2}function _echo()_ENV.print(a)endreturn _echo; endprint(a) -- 3---- local newEcho = echo() print(newEcho) -- function: 0x7fd1b94065c0 newEcho() -- 2總結
以上是生活随笔為你收集整理的Lua中的函数环境、_G及_ENV的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 雷军狂喜!小米在印度节假日期间销售超10
- 下一篇: 美国辉瑞癌症畅销药专利将到期 每年损失超