Lua中定义的基本类型如下:
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
#define LUA_NUMTAGS 9
正如Lua Document所说,Lua中只有8
个基本类型。但是,得到10
。我知道LUA_TLIGHTUSERDATA
和LUA_TUSERDATA
最终可以表示为userdata
,但LUA_TNONE
呢? none
和nil
的差异是什么?
答案 0 :(得分:3)
正如评论中已经提到的,在C API中使用4+4+4+4+4+4!=12
来检查是否存在 no 值。请考虑以下脚本:
none
在Lua中,您可以使用function foo(arg)
print(arg)
end
foo(nil) --> nil
foo() --> nil
获取传递给select('#', ...)
的参数数量,并使用C API检查用户是否提供了 no 参数(使用foo
)。考虑以下小型C库,其工作方式类似于lua_isnone
,但如果没有给出参数,它可以识别:
type
使用#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
static int which_type(lua_State* L)
{
// at first, we start with the check for no argument
// if this is false, there has to be at least one argument
if(lua_isnone(L, 1))
{
puts("none");
}
// now iterate through all arguments and print their type
int n = lua_gettop(L);
for(int i = 1; i <= n; ++i)
{
if(lua_isboolean(L, i))
{
puts("boolean");
}
else if(lua_istable(L, i))
{
puts("table");
}
else if(lua_isstring(L, i) && !lua_isnumber(L, i))
{
puts("string");
}
else if(lua_isnumber(L, i))
{
puts("number");
}
else if(lua_isfunction(L, i))
{
puts("function");
}
else if(lua_isnil(L, i))
{
puts("nil");
}
else if(lua_isthread(L, i))
{
puts("thread");
}
else if(lua_isuserdata(L, i))
{
puts("userdata");
}
}
return 0;
}
static const struct luaL_Reg testclib_functions[] = {
{ "type", which_type },
{ NULL, NULL }
};
int luaopen_testclib(lua_State* L)
{
luaL_newlib(L, testclib_functions);
return 1;
}
之类的内容进行编译。在lua中,我们现在加载库并使用函数gcc -shared -fPIC -o testclib.so testclib.c
:
type
请注意,您无法获得&#39;没有&#39;并且来自一次调用的另一种类型(虽然可以通过使用多个参数来接收多种类型,例如local p = require "testclib"
p.type(nil) --> nil
p.type({}) --> table
p.type("foo")) --> string
-- now call it without any arguments
p.type()) --> none, not nil
--type() -- error: bad argument #1 to 'type' (value expected)
)。这是非常合乎逻辑的,因为使用类似这样的东西会出现语法错误:
p.type("foo", 42)
可以在p.type(, 42) -- error
函数中看到这种情况的一种用法,其中print
打印值(即使它无效,例如print(something)
),其中nil
打印换行。