Lua 五二 |
|
虽然 5.1.x 版本严格来说只是 5.1 的 bug 修复版本[12][13][2],但 Lua 5.2 允许进行破坏完全兼容性的设计更改。
请随时更新参考资料! (以及此处的所有其他内容。) -- AlexanderGladysh
待办事项:以下某些部分可能需要更新以反映最终的 Lua 5.2.0 版本。
Lua 核心在分配失败时强制执行 GC。
参考资料
"generational"
LUA_GCGEN
只有当键可访问时,具有弱键的表才会访问值。
参考资料
具有终结器的用户数据在 GC 的一个单独列表中保留。
参考资料
Lua 解释器更好地处理非字符串错误消息。
参考资料
xpcall() 现在接受回调的 arguments,就像 pcall() 一样
参考资料
新函数 package.searchpath() 用于搜索您的文件,就像 require() 一样。
参考资料
现在记录了在 package.config 中可用的编译时模块系统设置。
参考资料
现在,借助新的 __pairs 和 __ipairs 元方法,可以重载循环迭代。
参考资料: GeneralizedPairsAndIpairs
除了字符串之外的所有类型现在都支持 __len 元方法。以前,__len 对于表是不支持的。
参考资料
string.format("%q") 现在可以转义控制字符。
参考资料
参考资料
除了旧的 \255 表示法之外,您还可以使用 \xFF 在字符串中写入。
参考资料
您可以使用 0x0.A 或 0xA23p-4 的形式编写数值常量。在后一种情况下,'p' 表示以十进制表示的二进制指数(手册没有明确说明:我假设指数将像其他部分一样是十六进制的)。此功能在手写代码中可能没有用,但它允许使用 string.format 的十六进制选项对使用十六进制序列化数字进行精确反序列化。
但是,尽管包含了官方的位操作库,但仍然不支持二进制字面量。
参考资料
%b
在 string.format
/ sprintf
中
os.date() 现在只允许 ANSI C 选项。
参考资料
新的 luaL_testudata API 函数,类似于 luaL_checkudata,但向调用者发出无效用户数据的信号,而不是抛出错误。
参考资料
如果第二个参数为零,则不再折叠除法和取模运算。
参考资料
现在您可以在元方法、for 循环迭代器、pcall 和 xpcall 调用以及现在未记录的 table.foreach[i] 调用中使用 yield()。
此外,还提供了 C API 调用来实现您自己的支持 yield 的 C 函数。
现在,您可以在 Lua 中操作位,而无需第三方模块或补丁。虽然没有使用任何现有的实现。
参考资料
Op)
现在 luaL_tolstring 已记录。您可以通过 tostring() 规则正式将 Lua 值从 C 转换。
参考资料: [20]
参考资料
_ENV
参考资料
getfenv() 和 setfenv() 已被新的词法环境取代。调试库的对应函数仍然存在。
参考资料
缓存匿名函数/闭包以供重用。由于移除了 getfenv/setfenv,现在可以进行此优化。待办事项:添加更好的描述和示例。
新的 loadin(env,chunk) 函数用于在给定环境中加载代码块。请注意,chunk
参数也可以是字符串。
fn,err = loadin({x=1,y=2},"return x+y")
参考资料
可以禁止加载字节码和/或源代码块。加载时的字节码验证已移除。
参考资料
Lua 线程(也称为协程)不再拥有独立的环境。
参考资料:(有吗?)
如预期,Lua 5.2 的 ABI 和字节码与 5.1 不兼容。
参考资料
5.1 中几乎所有弃用功能都被移除。新的弃用功能默认处于关闭状态。
参考资料:(有吗?)
如果需要,请使用 require() 加载。
luaL_openlibs
加载的列表中。--JohnHind
参考资料
linit.c
以前,协程库是基本库加载器函数加载的子库。在 5.2 中,它拥有自己的加载器函数,并升级为普通库。它包含在 luaL_openlibs
加载的列表中,因此此更改仅在运行时不使用 luaL_openlibs
时才重要。
手册中存在一个小错误:此更改反映在第 6 节中,但第 6.2 节仍然将其称为“基本库的子库”。
参考资料
linit.c, lcorolib.c
debug.getlocal 获取非活动函数的参数名称。在 debug.getlocal ([thread,] f, local)
中,“参数 f 也可以是一个函数。在这种情况下,getlocal 只返回函数参数的名称。”
参考资料
新增函数用于检测两个 upvalue 是否相同,以及在它们不同时将它们合并
参考资料
debug.getinfo() 和 lua_getinfo() 现在返回关于调用栈上函数的额外信息
参考资料:(有吗?)
边界模式现在已记录。
参考资料
新模式 %g
代表除空格之外的所有可打印字符。
string.gsub
[6] 现在如果替换字符串包含 '%' 后面跟着除允许的 '%' 或数字以外的字符,则会引发错误。
现在 ipairs() 迭代表中的 #t 个元素。在 5.1 中,它迭代到第一个 nil 为止。
参考资料: 源代码:lua-5.2.0-work4/src/lbaselib.c 第 213 行
您可以将负索引传递给 select() 以从可变参数的末尾获取参数(按直接顺序)。
参考资料
math.log10() 已弃用。使用 10 作为 math.log() 的新第二个参数。
参考资料:(有吗?)
table.maxn 已弃用。
参考资料
unpack() 重命名为 table.unpack()。添加 table.pack(),将参数打包到表中并将参数数量存储到表的字段 "n" 中。
参考资料
如果文件由 io.popen() 打开,file:close() 返回进程的退出代码。
参考资料
调用 collectgarbage("step") 不会再在 GC 停止时重新启动 GC。此外,您可以通过调用 collectgarbage("isrunning") 来判断 GC 是否已停止。当然,您也可以在 C API 中执行相同的操作。
参考资料:(有吗?)
Lua 标识符不再可以使用依赖于区域设置的字符。
参考资料
以下是 5.2.0 版本中 Lua 使用注册表 (在伪索引 LUA_REGISTRYINDEX
) 的完整列表。
由 lua_newstate 安装
由 'package' 库加载器安装
package.loaded
的引用
package.preload
的引用
由 'IO' 库加载器安装
手册中说明:“与全局名称一样,以下划线后跟大写字母开头的字符串键保留给 Lua。” 但是请注意,Lua 并没有严格遵循此规则,例如 "FILE*" 键。
字符串的元表尚未在注册表中引用,但它只是索引字符串库表本身,因此添加到该库表中的函数将自动作为字符串对象的函数。
参考资料
lua_pushcfunction 不再分配内存。这更有效率,并且不会在失败时引发错误。它还消除了对 lua_cpcall() 的需求,该函数已从 API 中移除。此外,由于 lua_pcall 现在可以支持多个参数和返回值,因此不再需要支持多个参数和返回值的 lua_cpcall 版本。
如果您需要它,请从注册表中使用 LUA_RIDX_GLOBALS(或者如果您没有更改 C 函数环境,则使用 LUA_ENVIRONINDEX)。
参考资料:(有吗?)
这些函数使用 C 函数环境而不是状态的全局环境,以更好地反映 Lua 处理全局变量的方式。
参考资料:(有吗?)
参考资料
添加了新函数 lua_compare() 来替换已弃用的 lua_equal() 和 lua_lessthan()。
参考资料
新函数 lua_arith() 用于像 Lua 一样对 Lua 值进行算术运算。
参考资料
lua_objlen() 已重命名为 lua_rawlen()。添加了 lua_len() 来支持 __len 元方法。
参考资料
lua_checkstack 现在只返回错误代码(从不抛出)。如果要抛出(带错误字符串),请使用 luaL_checkstack。
参考资料
现在它们返回指向内部字符串表示的指针。
参考资料:(有吗?)
允许在堆栈上复制 Lua 值(替换目标槽中的现有值)。
参考资料
添加了两个新函数 lua_version() 和 luaL_checkversion(),允许用户检查运行时版本和地址空间正确性。这将有助于防止在多个 Lua 实例链接到可执行文件时出现的可怕的难以理解的错误。luaL_checkversion() 从 luaL_register() 调用,因此当大多数模块被 require() 时,此类检查将自动执行。
参考资料
新函数用于生成堆栈跟踪,就像 debug.traceback() 一样。
参考资料
LUA_ERRGCMM 是一个新的运行时错误代码,用于表示 __gc 元方法中的错误。添加 LUA_OK 是为了保持对称性,表示一切正常,没有错误。
参考资料
现在 Lua C 模块可以使用全局符号加载动态库 (感谢 RTLD_GLOBAL)。
参考资料:(有吗?)
Windows 上的 DLL 搜索路径处理得到了改进。
LoadLibraryEx
。
每个块的最大常量数量从 2^18 增加到 2^26。去吧,巨大的表格转储!
参考资料
解析器消耗更少的 c-stack 空间,因为它不再使用自动数组。
参考资料
新的浮点数哈希函数,可以更好地处理在某些 64 位平台上 lua_Number 被定义为 long double 的情况。
参考资料
file:write() 返回文件以允许链式调用。
参考资料
文件:read 的新 "*L" 选项类似于 "*l",但保留换行符 (如果存在)。此外,file:lines 中的新 keepNL
参数保留换行符。
它可以选择在 Lua 状态上调用 lua_close()。
参考资料
"os.execute 函数现在在命令成功终止时返回 true,否则返回 nil 和错误信息。" [10]
示例
$ lua51 -e "os.exit(3)"; echo $? 3 $ lua51 -e 'print(os.execute[[lua -e "os.exit(3)"]])' 768 $ lua52 -e 'print(os.execute[[lua -e "os.exit(3)"]])' nil exit 3 $ perl -e 'print(system(qq(perl -e "exit(3)")),"\n")' 768 $ python -c "import os; print(os.system(\"python -c 'import os; os._exit(3)'\"))" 768
??
参考资料
module/luaL_register
函数已弃用,并被 luaL_newlib 和 luaL_setfuncs 替换。还新增了一个函数 luaL_requiref
。
我认为这比手册或其他资料中提到的变化要重大得多。表面上看,以前你可以写 require 'coroutine'
,例如,现在你必须写 coroutine = require 'coroutine'
。这绝对是一个有用的改进,但如果我理解正确的话,它会破坏很多现有的代码。手册的“更改”部分对此不够明确。更糟糕的是,require
的文档没有清楚地说明返回值的用途。你必须从字里行间读出,其目的是返回模块的全局表或值 'true',如果模块没有导出全局表(实现此意图取决于模块加载器遵循一些规则,这些规则没有明确说明)。
true
而不是模块表分配给 package.loaded[modname]
通常是应该避免的,并且更像是回退行为,缺乏任何更好的值可以使用,至少可以确保模块加载器在多次 require 调用时不会执行多次。现在,关于加载器应该返回什么,它通常应该是一个表 [21],但官方 Lua 参考手册可能对此保持沉默,因为 MechanismNotPolicy 设计原则。有时模块加载器会返回函数(通常是对象构造函数),尽管也许最好返回 FuncTables(即带有调用运算符的表),因为对于 require'foo'._VERSION
来表示模块版本 (ModuleVersioning) 是准标准的,这在 FuncTables 中仍然是可能的。顺便说一下,module
函数虽然在 5.2 中已弃用,但仍然可用,除非你关闭弃用功能,并且对 module
的调用会设置 package.loaded[modname]
(以及一个全局变量)。--DavidManura
比较 `luaL_requiref` (C API) 和 `require` (Lua):后者只接受模块名称,而前者接受模块名称、库加载器函数和一个标志,如果将该标志设置为 `true`,则将加载器函数的返回值存储在一个与库名称相同的全局变量中。`luaL_openlibs` 使用 `luaL_requiref` 并设置了此标志。因此,它将打开标准库,并按预期初始化其全局表。但是,从 Lua 使用 `require` 打开的库必须使用返回值显式设置全局变量。
如果您认为以上两段内容有误,请随时更正!
参考资料
添加了环境变量 LUA_PATH_5_2 等。
...或者我们会得到吗?
欢迎您在这里添加您的宠物功能,假设它得到了列表中其他人的支持,并且被 Lua 作者拒绝纳入 5.2 版本。请保持礼貌。--AlexanderGladysh
类似于 struct/lpack 的东西
参考资料
拒绝理由:(有链接吗?)
或其他“元”设施。
参考资料
拒绝理由:(有链接吗?)
这将类似于 C 预处理器的 #line
指令 [11]。主要目的是允许预处理器在生成的 Lua 代码中输出此指令,以便调试行号和文件名与原始(预处理前)源代码相对应。
Script“行号反转,因此在已编译的 Lua 中发生的错误将被重写为指向原始 Moon
Script 行”
__LINE__
用于 源代码优化器
从数字中获取一个没有强制转换的字符串。
参考资料
拒绝理由:(有链接吗?)
目前预计模块版本号位于名称的左侧,这很不寻常。
参考资料
拒绝理由:(有链接吗?)
用类似于 ModuleDefinition 中的 package.clean
解决方案替换 package.seeall,但更新为支持 _ENV。package.seeall 不会将公共模块表与私有实现环境分开。
参考资料
用户为 5.2 提出的某些功能/更改列在 FeatureProposals 中。请求应发布到邮件列表。