从C扩展函数内部确定Lua期望的返回值数量

时间:2018-08-20 13:33:14

标签: c lua

每次调用Lua中的函数时,都会在调用站点上立即知道返回值的数量:

f() --0
local a, b = f() --2
local t = {f()} --LUA_MULTRET
local t = {f(), nil} --1

C API也是如此:lua_calllua_pcall都始终提供预期数量的返回值(或LUA_MULTRET)。

考虑性能,对于Lua函数而言,能够确定其调用方表示的期望返回值的数量可能是有利的,从而避免计算调用方未请求的返回值(如果计算采用很长时间):

int getstrings(lua_State *L)
{
    if(lua_numresults(L) > 0)
    {
        lua_pushstring(L, "a");
        if(lua_numresults(L) > 1)
        {
            lua_pushstring(L, "b");
            if(lua_numresults(L) > 2)
            {
                lua_pushstring(L, "c");
                return 3
            }
            return 2;
        }
        return 1
    }
    return 0;
}

假设假设lua_numresults返回size_t,则此函数将仅生成真正需要的函数,而不会花费时间来计算保证丢失的值。

另一个有趣的示例是返回序列的函数:

int range(lua_State *L)
{
    size_t num = lua_numresults(L);
    for(size_t i = 1; i <= num; i++)
    {
        lua_pushinteger(L, i);
    }
    return num;
}

该序列不是“惰性”序列,因此无法完成类似f(range())的操作,但是local a, b, c = range()返回1、2、3等可能会发现其用途。

是否有类似lua_numresults之类的东西或实现其功能的方式?

1 个答案:

答案 0 :(得分:2)

从Lua 5.3的来源来看,预期的结果数位于CallInfo结构中。每个Lua调用都会创建一个新的调用信息,而最新的调用信息将存储在lua_State::ci中。似乎没有任何函数可以返回此值,但是如果一个人可以访问该结构,则返回相当简单:

#include "lua/lstate.h"

size_t lua_numresults(lua_State *L)
{
    return (size_t)L->ci->nresults;
}