澄清(抱歉问题不具体):他们都试图将堆栈上的项目转换为lua_Number
。 lua_tonumber
还将转换表示数字的字符串。 luaL_checknumber
如何处理不是数字的东西?
还有luaL_checklong
和luaL_checkinteger
。它们分别与(int)luaL_checknumber
和(long)luaL_checknumber
相同吗?
答案 0 :(得分:10)
参考手册确实回答了这个问题。我引用了Lua 5.2参考手册,但同样的文字也在5.1手册中找到。但是,手册非常简洁。任何单一事实很难在一个以上的句子中重述。此外,您经常需要关联广泛分离的部分中陈述的事实,以了解API函数的深层含义。
这不是缺陷,而是设计上的。这是该语言的参考手册,因此其主要目标是完全(和正确)描述该语言。
有关"如何"的更多信息和"为什么"一般的建议是阅读Programming in Lua。由于它描述了Lua 5.0,因此在线版本的版本相当长。目前的纸质版本描述了Lua 5.1,并且正在编写一个描述Lua 5.2的新版本。也就是说,即使是第一版也是一个很好的资源,只要你也注意自5.0版本以来语言的变化。
参考手册对于luaL_check*
函数系列有相当多的说法。
每个API条目的文档块都附带一个描述其堆栈使用的标记,并在什么条件下(如果有的话)会引发错误。这些令牌在section 4.8:
中描述每个函数都有一个如下指示符:
[-o, +p, x]
第一个字段o是函数弹出的元素数量 堆。第二个字段p是函数推送的元素数量 到堆栈上。 (任何功能总是在弹出后推送其结果 它的参数。)x | y形式的字段表示函数可以推送 (或弹出)x或y元素,视情况而定;审讯 标记'?'意味着我们无法知道这个功能有多少元素 通过仅查看其参数来弹出/推动(例如,它们可能依赖于 什么在堆栈上)。第三个字段x告诉函数是否正常 可能会抛出错误:' - '意味着函数永远不会抛出任何错误; ' E' 意味着该函数可能会抛出错误; ' V'意味着该功能可能会抛出 故意错误。
在第5章的头部,它记录了整个辅助库(官方API中的所有函数,其名称以luaL_
开头,而不仅仅是lua_
),我们发现:
辅助库中的几个函数用于检查C. 函数参数。因为错误消息的格式为 参数(例如,"错误的参数#1和#34;),你不应该使用这些 其他堆栈值的函数。
如果检查不是,则称为luaL_check *的函数总是抛出错误 满意。
函数luaL_checknumber
记录了令牌[-0,+0,v]
,这意味着它不会打扰堆栈(它不会弹出任何内容并且什么也不推送),并且可能故意抛出错误。
具有更多特定数字类型的其他函数主要在函数签名中有所不同。所有内容都与luaL_checkint()
&#34类似地进行描述;检查函数参数arg
是否为数字并将此数字转换为int
",改变在lua_tonumber()
中指定的类型适当地施放。
使用令牌[-0,+0,-]
描述函数lua_tonumberx()
,这意味着它对堆栈没有影响,并且不会抛出任何错误。记录为从指定的堆栈索引返回数值,如果堆栈索引不包含足够数字的值,则返回0。记录使用更通用的函数lauxlib.c
,它还提供一个标志,指示它是否成功转换了数字。
它也有以更具体的数字类型命名的兄弟姐妹,这些数字类型执行所有相同的转换但是转换结果。
最后,还可以参考源代码,并理解手册是按照预期描述语言,而源是该语言的特定实现,可能有错误,或者可能揭示实现在未来版本中可能会更改的详细信息。
luaL_checknumber()
的来源位于lua_tonumberx()
。可以看出,它是以tagerror()
和内部函数typerror()
实现的,它调用{{1}}实现了luaL_argerror()
以实际抛出格式化的错误消息。
答案 1 :(得分:1)
他们都试图将堆栈上的项目转换为lua_Number。 lua_tonumber还将转换表示数字的字符串。 luaL_checknumber在转换失败时抛出(Lua)错误 - 它跳转并且永远不会从C函数的POV返回。 lua_tonumber只返回0(也可以是有效的返回。)所以你可以编写这个代码,这比首先用lua_isnumber检查要快。
double r = lua_tonumber(_L, idx);
if (r == 0 && !lua_isnumber(_L, idx))
{
// Error handling code
}
return r;