Lua的版本差別確實是比較讓人頭疼的事情,以前在移動端一直採用Android下使用LuaJit,Ios下使用Lua5.1。此次升級到Xlua(lua5.3版本)主要有兩方面的緣由:一是ulua後續維護比價差,決定要升級到xlua,另外一方面是公司在上線檢查中提示禁止Luajit的使用(一些Crash沒法解決),固然順便解決了bit、64位問題。html
參考:5.1 到 5.2 、5.2 到 5.3 、雲風:Lua 5.2 的細節改變git
5.2中拋棄module,建議使用require進行加載, 多是考慮到Module定義對全局表的污染, 參考:抵制使用 module() 定義模塊
解決方案:github
local base = _ENV local modname = {} local _ENV = modname ... return modname
在5.1版本,能夠理解爲每一個chunk都具備本身的環境表,而後經過setfenv/getfenv進行設置和操做。Lua5.2開始取消了環境表的概念,取消setfenv/getfenv方法,增長了_Env來管理。閉包
-- Lua 5.1 function foobar() setfenv(1, {}) -- code here end -- Lua 5.2 function foobar() local _ENV = {} -- code here end
_G 是放在註冊表LUA_RIDX_GLOBALS中,初始化時核心的庫都放在_G中;_Env 是chunk閉包的第一個upvalue,load時默認爲_G, 而後後面定義的變量都會在編譯時加上_ENV.前綴,以此傳遞下去,固然也能夠修改。lua的註冊表,_ENV,_G 底層實現從源代碼層級對兩者之間的區別進行了討論。若是想要修改環境的同時還能訪問全局變量dom
a = 1 local newgt = () setmetatable(newgt, {__index = _G}) _ENV = newgt print(a) --> 1 a = 10 print(a) --> 10 print(_G.a) --> 1 _G.a = 20 print(_G.a) --> 20
5.2開始在Debug 類中提供了一些列關於upvalue操做的函數,經過這個方法能夠實現相似5.1中setfenv/getfenv的操做方式。詳細的過程能夠參考 這兩篇文章:
Implementing setfenv in Lua 5.2, 5.3, and above
Converting setfenv getfenv to Lua 5.2ide
local function getfenv(fn) local i = 1 while true do local name, val = debug.getupvalue(fn, i) if name == "_ENV" then return val elseif not name then break end i = i + 1 end end local function setfenv(fn, env) local i = 1 while true do local name = debug.getupvalue(fn, i) if name == "_ENV" then debug.upvaluejoin(fn, i, (function() return env end), 1) break elseif not name then break end i = i + 1 end return fn end
在5.2中已經移除了LUA_GLOBALSINDEX,去而帶之的是註冊表。5.2之後中上面兩個函數都是使用的註冊標中的LUA_RIDX_GLOBAS僞索引(索引註冊表的全局環境)。處理 lua和C交互API的時候須要注意函數
Lua5.2 之後取消了這個接口,不過能夠經過luaL_setfunc方法看來實現大數據
#undef luaL_register #define luaL_register(L,n,f) \ { if ((n) == NULL) luaL_setfuncs(L,f,0); else luaL_newlib(L,f); } #endif
Lua5.3 默認支持64位整數和浮點數,固然也能夠經過luaconf.h修改成32位。默認爲64位以後徐須要注意的是:ui
從luajit升級到5.3版本問題都比較零碎,除了上面幾個問題,還包括:lua
github上也能夠找到一些實現好的類庫來知足不一樣版本之間的兼容,好比:Lua向下兼容github 庫、Lua不一樣版本間兼容資源
lua的註冊表,_ENV,_G 底層實現
抵制使用 module() 定義模塊
雲風 lua 5.2 的 _ENV
對lua中_ENV表的理解
Env環境
Implementing setfenv in Lua 5.2, 5.3, and above
Converting setfenv getfenv to Lua 5.2
Lua向下兼容github 庫
Lua不一樣版本間兼容資源