lua中的_ENV

在lua中,至少從5.2開始就不再有全局變量:

當你寫a = 1的時候,其實被編譯成 _ENV.a = 1

但是一直以為_ENV是全局environment,其實不然,lua手冊中說:

every chunk is compiled in the scope of an external local variable called _ENV (see §3.3.2), so _ENV itself is never a global name in a chunk.

這里的external local variable就是upvalue,也就是_ENV是當前chunk的upvalue。

When Lua compiles a chunk, it initializes the value of its _ENV upvalue with the global environment (see load).

當lua編譯一個chunk的時候,如果不指定的話,默認使用全局environment初始化它的upvalue _ENV(其實就是引用),它是隱式聲明的一個upvalue,看load聲明:

load (ld [, source [, mode [, env]])
loadfile ([filename [, mode [, env]])

所以_ENV是語法糖,它在lua編譯的作為upvalue被隱式聲明,并且可以由外部指定。
通過下面代碼可以驗證:

t.lua
local _env = {tostring=tostring,print=print, debug=debug} 
print ("_ENV = "..tostring(_ENV))                         
print ("_env = "..tostring(_env))                         
local f, err = loadfile("m.lua", "bt", _env)              
assert(f, err)                                            
local m = f(f)                                            
m.test()                                                  
m.lua
local f = ...                              
local m = {}                               
                                           
function m.test()                          
    local i =1                             
    while true do                          
        local n, v = debug.getupvalue(f, i)
        if not n then                      
            break                                                        
        elseif n == "_ENV" then                
            print ("_ENV = "..tostring(v)) 
            break                          
        end                                
        i = i+1                            
    end                                    
end                                        
                                           
return m                               
輸出
_ENV = table: 0x132f5f0
_env  = table: 0x1335f90
_ENV = table: 0x1335f90

查看指令碼可以看到SETUPVAL:

t.lua
_ENV = nil 
$ luac -l t.lua
main <t.lua:0,0> (3 instructions at 0x245b3c0)
0+ params, 2 slots, 1 upvalue, 0 locals, 0 constants, 0 functions
        1       [47]    LOADNIL         0 0
        2       [47]    SETUPVAL      0 0     ; _ENV
        3       [47]    RETURN          0 1

ps:
全局environment在C Registry(LUA_REGISTRYINDEX):LUA_RIDX_GLOBALS: At this index the registry has the global environment.
_G在初始化的時候被復制為全局environment。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評論 19 139
  • 說明本次redis集群安裝在rhel6.8 64位機器上,redis版本為3.2.8,redis的gem文件版本為...
    讀或?qū)?/span>閱讀 15,633評論 3 9
  • =========================================================...
    lavor閱讀 3,649評論 0 5
  • 一個人的心情永遠是寂寥的。一種無奈填滿了心頭,那不是相思。孤枕難眠,人生好像有太多這樣的夜晚,這樣的無奈,最先爬上...
    香齋主人閱讀 432評論 2 2
  • 生活還是要有夢想。我想自己有做夢的權(quán)利。在可以知道干什么的時候,讓自己去做點有意義的事情。12月,等結(jié)果;堅持運動...
    Molly_05閱讀 306評論 0 0

友情鏈接更多精彩內(nèi)容