以Python方式调用Lua函数,即命名参数

4

我有50多个C++函数,它们接受一个固定数量的参数,比如25个以上。将这些参数视为数据结构内的成员。

每个函数实现业务逻辑时可能需要读取/检查所有25个参数的值,也可能只对其中2个值感兴趣,而其他需要进行多次检查的函数则可能查找15个以上。

以下是一些示例函数:

C++

void DrawSegment(int length);
void DrawCircle(int radius);
void DrawRectangle(int width, int height);
void DrawCube(int side);

我的任务是在Lua中提供一个易于使用的接口方法来调用这些函数。类似于:

DrawShape("CIRCLE", 20)
DrawShape("RECTANGLE", 10, 20)

Lua-C++绑定代码:

enum TYPE{SEGMENT, CIRCLE, RECTANGLE, CUBE};

lua_Integer MapStringToEnum(const char*);

int lua_DrawShape(lua_State*L)
{
        lua_Integer type = MapStringToEnum(lua_tointeger(L, -1));
        switch (type)
        {
        case SEGMENT:
                DrawSegment(lua_tointeger(L, -2)); // length
                break;
        case CIRCLE:
                DrawCircle(lua_tointeger(L, -2));  // radius
                break;
        case RECTANGLE:
                DrawCircle(lua_tointeger(L, -2), lua_tointeger(L, -3)); // width, height
                break;
                ...
                //and so on for other types
        default:
                ASSERT(0);
        };
}

initShapeLibrary(lua_State* L)
{
    lua_pushcfunction(L, lua_DrawShape);
    lua_setglobal(L, "DrawShape");
}

我面临的挑战是,由于每个函数都不需要所有的参数,如何使用户更容易指定这些字段?一种方法是记录参数及其顺序,并期望用户遵循它。但这只会导致代码难以阅读,迫使用户指定他不打算传递的空值或空字符串。

-- 1st argument is radius, 2nd unused.
DrawShape("CIRCLE", 20, -1) 

这不利于编写代码。我真正想要的是类似Python的功能,使得代码更易读。
DrawShape("CIRCLE", Radius=20)

有没有通过Lua实现这个的方法?如果没有,我打算对参数字符串进行分词,然后设置各个参数的值。

您的反馈将有所帮助。非常感谢。

1个回答

4

DrawShape("CIRCLE", Radius=20)

您可以传递一个表格,这将允许您区分位置参数和命名参数:

DrawShape({"CIRCLE", Radius=20})

您还可以使用语法糖,在这种情况下,您可以省略一对括号:

DrawShape{"CIRCLE", Radius=20}

您可以使用unpack(t)(假设您传递的参数是t)获取位置参数,使用t.Radius获取其余参数或使用pairs迭代它们。

个人而言,我仍然会坚持使用DrawCubeDrawCircle...


使用表格是一个很酷的技巧!“unpack”似乎仅限于Lua。对于C++部分,我可能需要遍历表格。这样对吗? - Amit
是的,你可以使用“pairs”迭代表中的元素或使用“ipairs”或“1,#t”范围的“for”循环访问位置元素。 - Paul Kulchenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接