与 Lua 五的兼容性 |
|
此页面的主要目标与 [Compat5-1] 相同,但形式是一组提示,而不是一组文件。
Hisham 制作了一个 [为 Lua 5.1 提供 Lua-5.2 风格 API 的兼容性模块]。
参考资料
(括号中表示更改针对的目标 Lua 版本)
require()
的调用 (Lua 5.0 和 5.1)
重写对 require
的调用以保存其返回值(另请参见下面的“module()”)。例如
require"lib"
变为
local lib = require"lib"
参考资料
module()
(Lua 5.1)
可以删除对 module()
的调用,并且代码应该被修改为返回一个包含导出函数的表。有不同的方法可以修改代码。最简单的方法是
local function func1(...) ... end local function func2(...) ... end return { func1 = func1, func2 = func2, }
某些模块可能需要另一种方法,例如
local _M = {} function _M.func1(...) ... end function _M.func2(...) ... end return _M
参考资料
从 Lua 5.0 到 Lua 5.2 与环境相关的更改很棘手,应该手动更正。
table.getn()
的调用 (Lua 5.0)
table.getn
仅在 Lua 5.0 中定义,长度运算符 是在以下版本中推荐的替代方法(参见 [关于 table.getn
弃用的说明])。
如果 table.getn
仅在测试文件中使用,则可以定义
if string.find(_VERSION, " 5.0") then table.getn = function (t) if t.n then return t.n else local n = 0 for i in pairs(t) do if type(i) == "number" then n = math.max(n, i) end end return n end end end
尽管在这种情况下应该考虑为不同版本的 Lua 分发单独的文件。
for
结构 (Lua 5.0)旧的结构应该很容易转换为与 Lua 5.X 兼容的形式
for i,v in t do ... end
应该重写为
for i,v in pairs(t) do ... end
参考资料
for
和 repeat
中变量的作用域 (Lua 5.0)
从 Lua 5.0 到 Lua 5.1,隐式 for
变量和 repeat
中的局部变量的作用域发生了变化。这必须手动检查。
参考资料
无法编写与所有 Lua 5.X 版本兼容的嵌套长字符串。应手动调整代码以避免这些结构。
自 Lua 5.1 起,定义了函数 lua_pushinteger
。尽管它是一个函数,但以下宏将使 Lua 5.1/5.2 代码向后兼容 Lua 5.0
#if !defined(LUA_VERSION_NUM) #define lua_pushinteger(L, n) lua_pushnumber(L, (lua_Number)n) #endif
luaL_reg
(Lua 5.0)自 Lua 5.1 起更名为 luaL_Reg
。这可以通过条件编译来解决
#if !defined LUA_VERSION_NUM /* Lua 5.0 */ #define luaL_Reg luaL_reg #endif
自 Lua 5.1 起,定义了函数 lua_setfield
。因此,可以定义以下宏以使 Lua 5.1/5.2 代码向后兼容 Lua 5.0
#if !defined(LUA_VERSION_NUM) #define lua_setfield(L, i, k) (lua_pushstring(L, k), lua_settable(L, i)) #endif
已弃用的函数 lua_getref()
和 lua_unref()
很容易转换为兼容的调用。例如
/* This code is compatible with previous versions (4.0) */ lua_getref(L, ref); lua_unref(L, ref);
应该重写为
/* This is Lua 5.X code *; lua_rawgeti(L, LUA_REGISTRYINDEX, ref); luaL_unref(L, LUA_REGISTRYINDEX, ref);
只要有一个函数:luaL_setfuncs
,Lua 5.2 模块就很容易与之前的 Lua 5.X 版本兼容。
#if !defined LUA_VERSION_NUM || LUA_VERSION_NUM==501 /* ** Adapted from Lua 5.2.0 */ static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { luaL_checkstack(L, nup+1, "too many upvalues"); for (; l->name != NULL; l++) { /* fill the table with given functions */ int i; lua_pushstring(L, l->name); for (i = 0; i < nup; i++) /* copy upvalues to the top */ lua_pushvalue(L, -(nup+1)); lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ lua_settable(L, -(nup + 3)); } lua_pop(L, nup); /* remove upvalues */ } #endif
此外,应根据其**第二个**参数更改对 luaL_openlib()
和 luaL_register()
的调用。
例如 luaL_openlib(L, NULL, lreg, x);
应改写为 luaL_setfuncs(L, lreg, x);
。
例如 luaL_openlib(L, name, lreg, x);
应谨慎改写,因为将搜索并可能创建具有给定名称的全局表。
例如 luaL_register(L, NULL, lreg);
应改写为 luaL_setfuncs(L, lreg, 0);
。
例如 luaL_register(L, name, lreg);
应谨慎改写,因为将搜索并可能创建具有给定名称的全局表。如果可能,应改写为 luaL_setfuncs(L, lreg, 0);