从C中的Lua函数返回'nil'与返回0值

时间:2013-08-29 23:01:55

标签: c lua

某些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"。我不知道这有多重要。

3 个答案:

答案 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)

(这不是答案,只是关于这个问题的意见)

至于我,nilno 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?

恕我直言,函数的参数传递必须完全符合赋值语句的语义。