Lua5.1到Lua5.2的差异

发布时间 2023-04-23 18:04:51作者: lsgxeva

Lua5.1到Lua5.2的差异

来源  https://zhuanlan.zhihu.com/p/96009862

 

版本差异

这一节列出Lua5.1到Lua5.2,以及Lua5.2到Lua5.3的版本差异。目前使用得最多的版本可能是Lua5.1这个版本,但是我很推荐将Lua升级到最新的5.3,因为5.3解决了5.1的一些缺陷并带来了一些很不错的功能(比如位操作,整型支持,utf-8解码库等等)。

所以这一篇就不全按参考手册来了,只列出版本差异之处。

Lua5.1到Lua5.2的差异

语言更改

  • 环境(environment)的概念改变了,只有Lua函数才有环境。要设置Lua函数的环境,请使用变量_ENV或load函数。

C函数不再有环境,如果你想在多个C函数之间保持共享状态,请对共享表使用upvalue。(你可以使用luaL_setfuncs打开一个C库,并使该库的函数共享一个公共的upvalue)。

要操纵用户数据的“环境”(现在称为用户数据),请使用新函数 lua_getuservalue 和 lua_setuservalue.

  • Lua标识符不能使用与语言环境相关的字母。
  • 如果垃圾收集器已停止,则在垃圾收集器中执行一步或全量的回收不会重启收集器。
  • 带有弱键的弱表现在执行起来像ephemeron表。
  • 在调试Hook中"tail return"事件被删除。取而代之的是尾调用产生一个特殊的新事件:tail call,这样调试器就可以知道不会有相应的返回事件。
  • 函数值之间的相等性已更改。现在,一个函数定义可能不会创建一个新值出来,如果新函数和某些以前的值没有明显的区别,则可能会重用这些值。

库更改

  • module函数已被弃用。使用常规的Lua代码设置一个模块很容易。不再期望模块设置全局变量。
  • setfenv和getfenv函数被删除,因为环境概念的更改。
  • math.log10函数已被弃用。可以使用math.log并向第2个参数传入10来代替。
  • loadstring函数已被弃用。使用load代替,它现在可以接受字符串参数且等同于loadstring。
  • table.maxn函数已被弃用。如果你确实需要请在Lua中自己实现。
  • os.execute函数现在如果命令成功终止则返回true,否则返回nil和一个错误消息。
  • unpack函数被移到table库中,因此要改成这样调用 table.unpack。
  • 模式中的字符类%z已被弃用,因为现在模式可以包含\0作为正常字符。
  • 表package.loaders重命名为package.searchers。
  • Lua不再有字节码验证。所以,所有加载代码的函数(load和loadfile)在加载不信任的二进制数据时都可能有潜在的不安全。(实际上,由于验证算法的缺陷,这些函数一直都是不安全的)。如有疑惑,请将这些函数的mode参数限制为只加载文本的块。
  • 官方发布包中的标准路径可能会在不同版本间修改。

API更改

  • 伪索引LUA_GLOBALSINDEX被删除了,你必须从注册表中取得全局环境。
  • 伪索引LUA_ENVIRONINDEX ,和函数lua_getfenv/lua_setfenv被删除了,因为C函数不再需要环境。
  • luaL_register被弃用。用luaL_setfuncs以使你的模块不会创建全局变量(不再期望模块设置全局变量)。
  • 分配函数中的osize在分配新块时(也就是当ptr是NULL时)可以不为0,。仅使用ptr==NULL来判断块是不是新的。
  • 用户数据的终结器(__gc元方法)与它们标记为可终结的顺序相反,而不是它们创建的顺序。(大多数用户数据在创建完之后会马上标记为可终结)。而且如果在设置元表时,元表没有gc字段,即使它在后面补上了,终结器也不会被调用。
  • luaL_typerror被删除了,如果你需要它请自己编写。
  • lua_cpcall函数被弃用。你可以简单的通过lua_pushcfunction压入函数,然后通过lua_pcall调用它。
  • lua_equal 和 lua_lessthan 被弃用。使用新的lua_compare并带上合适的选项来代替。
  • lua_objlen函数重命名为lua_rawlen.
  • lua_load 函数有一个额外的参数mode,如果传NULL则和老版本的行为一致。
  • lua_resume 函数有一个额外的参数from,传NULL或是该线程执行了调用。

Lua5.2到Lua5.3的差异

语言更改

  • 5.2到5.3的主要差异是为number引入了一个integer子类型。尽管这个改变不会影响“正常”的计算,但有些计算会产生不同的结果(主要涉及到一些类型的溢出)

你可以通过将一个数字强制为浮点数来解决这个问题。(Lua5.2中所有数字都是浮点数),特别是以.0结尾的常量,或者使用x = x + 0.0来转换变量。(这个建议只是对偶尔的一些不兼容的一个快速修正,而不是良好编程的通用指南。为了良好的编程效果,请在需要浮点数的地方使用浮点数,在需要整数的地方使用整数)

  • 如果一个浮点数看起来像一个整数,它转为字符串时会在结果加一个.0后缀。(比如浮点数2.0将打印为2.0,而不是2) 当你需要数字的特定格式时,应始终使用明确的格式。

(在形式上这不是不兼容,因为Lua没有指定一个数字如何格式化为字符串,但一些程序采用了特定的格式)

  • 垃圾收集器的分代模式被删除了(这是Lua5.2的试验特性)

库更改

  • bit32库已丢弃。很容易使用一个兼容的外部库,或者更好的做法是将这些函数替换为位运算操作。(注意byt32操作的是32位整数,而Lua5.3的位运算符操作的是Lua整数,它默认为64位整数)
  • table库现在遵循设置和获取元素的元方法。
  • io.load的选项名不再需要"*"开头。为了兼容性,Lua仍然接受(并且忽略)这个字符。
  • 数学库的下面函数被丢弃:atan2, cosh, sinh, tanh, pow, frexp, 和 ldexp。你可以将math.pow(x, y)替换为x^y;你可以将math.atan2替换为math.atan(该函数接受一或两个参数);你可以替换math.ldexp(x,exp)为x * 2.0^exp。对于其他操作,你可以使用扩展库,或自己实现它们。
  • require使用的C加载器的搜索器,改变了它处理版本名字的方式。现在,版本应跟在模块名后面(与其他大多数工具一样)。为了兼容性,搜索器如果根据新格式找不到函数,会尝试使用旧的格式。(Lua 5.2已经这样工作了,但是它没有记录更改)。
  • collectgarbage("count")仅返回一个结果(你可以根据第一个结果的小数部分来计算第二个结果。)

API更改

  • 延续函数将原来通过lua_getctx返回所需要的信息改为通过参数传递,所以lua_getctx被删除掉了。要相应地调整你的代码。
  • lua_dump函数有一个额外的参数strip,参数为0时等于旧版本的行为(即保留调试信息,为1则删除调试信息)。
  • 压入和获取无符号整型的函数已被丢弃(lua_pushunsigned, lua_tounsigned, lua_tounsignedx, luaL_checkunsigned, luaL_optunsigned)。使用有符号的相等值进行类型转换。
  • 获取非默认整型的宏已被丢弃(luaL_checkint, luaL_optint, luaL_checklong, luaL_optlong),通过lua_Integer上的相等进行类型转换。(或者可能的话,在你的代码中使用lua_Integer)。

 

 

=========== End