简体   繁体   English

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

[英]Returning 'nil' from a Lua function in C vs returning 0 values

Some Lua functions return nil to signal the user that the function couldn't carry out some task (eg, tonumber() , string.find() ). 一些Lua函数返回nil以通知用户该函数无法执行某些任务(例如, tonumber()string.find() )。

In C, returnig nil is done like this: 在C中,returnig nil是这样完成的:

int some_function(lua_State* L) {
  ...
  if (some condition) {
      lua_pushnil(L);
      return 1;
  }
  ...
}

HOWEVER, I wonder if it's alright to do the following instead: 但是,我想知道是否可以做以下事情:

int some_function(lua_State* L) {
  ...
  if (some condition) {
      return 0;
  }
  ...
}

It's shorter. 它更短。 I tried it and it seems to works, but I don't know if that's by-design. 我尝试了它似乎有效,但我不知道这是否是按设计的。 I examined Lua's source code and I don't see this return 0 pattern so I wonder if it's legit to do this. 我检查了Lua的源代码,我没有看到这个return 0模式,所以我想知道这样做是否合法。

Are the two different ways to return nil equivalent? 返回nil的两种不同方式是否相同?

(BTW, I know all about signaling errors via exceptions (that is, lua_error() ) so please don't mention it.) (顺便说一句,我知道所有关于通过异常发出的信号错误(即lua_error() )所以请不要提及它。)

UPDATE: 更新:

I now see that there's a subtle difference between the two methods: print((function() end)()) would print nothing whereas print((function() return nil end)()) would print "nil". 我现在看到两种方法之间存在细微的差别: print((function() end)())什么都不print((function() return nil end)())print((function() return nil end)())会打印“nil”。 I don't know how important this is. 我不知道这有多重要。

Functions in Lua may return nil but may also return nothing, and this behavior is not exactly equivalent, although in most context will produce the same results. Lua中的函数可能返回nil但也可能不返回任何内容,并且这种行为并不完全等效,尽管在大多数情况下会产生相同的结果。

The following Lua script shows you how to detect how many return values a function returns: 以下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

I said the behavior is almost equivalent because as soon as you try to assign to a variable the result of a function that variable will get nil in both cases, thus the subsequent code won't be able to tell the difference. 我说行为几乎是等价的,因为只要你尝试为一个变量分配一个函数的结果,变量在两种情况下都会得到nil ,因此后续的代码将无法区分。 But, as I showed above, you can detect the difference if you really need. 但是,正如我上面所示,如果你真的需要,你可以发现差异。

Yes, this is perfectly valid. 是的,这是完全有效的。 If you're trying to request/assign more return values than there are (no matter whether you try to get one or ten), you'll get nil for the undefined ones (ie those not returned). 如果您尝试请求/分配的返回值多于(无论您是尝试获得一个还是十个),那么对于未定义的(即未返回的那些),您将获得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

You probably can't find it in Lua's source because it's no special case or anything. 您可能无法在Lua的源代码中找到它,因为它不是特例或任何特殊情况。 It's just Lua's generic way to handle return values. 这只是Lua处理返回值的通用方法。

Update: 更新:

The difference you've noticed when trying to print return values is the fact that this is not just an assignment. 您在尝试打印返回值时注意到的差异是,这不仅仅是一项任务。 Of course there is a slight difference between returning nil and returning nothing at all - and it's possible to differentiate there. 当然,在返回nil和返回任何内容之间存在细微差别 - 并且可以在那里区分。 In the end you'll just have to make sure you document your function's behavior properly, ie tell the user what's supposed to happen. 最后,您必须确保正确记录您的功能行为,即告诉用户应该发生什么。 For example, returning nil (or getting nil in an assignment) could represent an error state, but it's also possible to return nothing in case there's been an error and return nil if some value is supposed to be invalid or nil (but no error happened). 例如,返回nil (或得到nil在分配中)可以代表一个错误状态,但它也有可能没有的情况下,返回的决定有错误,返回nil ,如果某个值应该是无效的或nil (但没有发生错误)。

(This is not an answer, just an opinion about the subject) (这不是答案,只是关于这个问题的意见)

As for me, this artifical difference between nil and no value is inconsistent and rather annoying. 对于我来说,这之间的差别人工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?

IMHO, function's parameter passing must fully comply with semantic of assignment statement. 恕我直言,函数的参数传递必须完全符合赋值语句的语义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM