某些Lua函数返回nil
以通知用户该函数无法执行某项任务(例如tonumber()
,string.find()
)。
在C中,returnig nil
就是这样完成的:
int some_function(lua_State* L) {
...
if (some condition) {
lua_pushnil(L);
return 1;
}
...
}
但是,我想知道是否可以做以下事情:
int some_function(lua_State* L) {
...
if (some condition) {
return 0;
}
...
}
它更短。我尝试了它似乎有效,但我不知道这是否是按照设计的。我检查了Lua的源代码,但我没有看到这种return 0
模式,所以我想知道这样做是否合法。
两种不同的方法是返回nil
等效吗?
(顺便说一句,我知道所有关于通过例外的信号错误(即lua_error()
),所以请不要提及。)
更新
我现在看到两种方法之间存在细微差别:print((function() end)())
不会打印任何内容,而print((function() return nil end)())
会打印" nil"。我不知道这有多重要。
答案 0 :(得分:13)
Lua中的函数可能返回nil
但也可能不返回任何内容,并且这种行为并不完全等效,尽管在大多数情况下会产生相同的结果。
以下Lua脚本向您展示了如何检测函数返回的返回值的数量:
local function PrintNRetVals( ... )
local nargs = select( '#', ... )
print( "Number of values returned: " .. nargs )
end
local function ReturningSomething()
return "hello"
end
local function ReturningNil()
return nil
end
local function ReturningNothing()
return
end
PrintNRetVals( ReturningSomething() ) --> 1
PrintNRetVals( ReturningNil() ) --> 1
PrintNRetVals( ReturningNothing() ) --> 0
我说行为几乎是等价的,因为只要你尝试将一个函数的结果分配给变量,变量在两种情况下都会得到nil
,因此后续的代码将无法分辨区别。但是,正如我上面所示,如果你真的需要,你可以发现差异。
答案 1 :(得分:5)
是的,这完全有效。如果您尝试请求/分配的返回值多于(无论您是尝试获得一个还是十个),那么对于未定义的(即未返回的那些),您将获得nil
。
function test1()
return 5
end
local a, b = test1()
-- a = 5, b = nil
function test2()
return 1, 2
end
local c, d, e = test2()
-- c = 1, d = 2, e = nil
function test3()
end
local f, g = test3()
-- f = nil, g = nil
你可能无法在Lua的源代码中找到它,因为它不是特例或任何特殊情况。这只是Lua处理返回值的通用方法。
更新
在尝试打印返回值时,您注意到的差异在于这不仅仅是一项任务。当然,返回nil
并且根本不返回任何东西之间会有一些细微差别 - 并且可以区分它们。最后,您必须确保正确记录您的功能行为,即告诉用户应该发生什么。例如,在赋值中返回nil
(或获取nil
)可能表示错误状态,但如果出现错误,也可以不返回任何内容,如果有值则返回nil
应该是无效的或nil
(但没有发生错误)。
答案 2 :(得分:2)
(这不是答案,只是关于这个问题的意见)
至于我,nil
和no value
之间的这种人为差异是不一致的,而且很烦人。
local function f1() return nil end
local function f0() end
local v1 = f1() -- OK, assigns nil
print(type(f1())) -- OK, prints 'nil'
local v0 = f0() -- OK, assigns nil
print(type(f0())) -- Why the hack it raises an error?
恕我直言,函数的参数传递必须完全符合赋值语句的语义。