为什么在Lua中使用索引方法而不是特殊方法

-- 创建一个 lua_State* 实例
lua_State* m_state;
-- 创建新的 metatable,命名为 LUA_DATACLIENT
luaL_newmetatable(m_state, LUA_DATACLIENT);

-- 给 metatable 加上 __index 方法,用于表索引操作
lua_pushcfunction(m_state, DataClient_Index);
lua_setfield(m_state, -2, "__index");

-- 给 metatable 加上 __newindex 方法,用于表赋值操作
lua_pushcfunction(m_state, DataClient_newIndex);
lua_setfield(m_state, -2, "__newindex");

-- 给 metatable 加上 RequestData 方法,方便在 Lua 中调用
lua_pushcfunction(m_state, DataClient_RequestData);
lua_setfield(m_state, -2, "RequestData");

-- 给 metatable 加上 __gc 方法,用于在 Lua 中通过 GC 释放资源
lua_pushcfunction(m_state, DataClient_free);
lua_setfield(m_state, -2, "__gc");
-- 弹出一次栈顶元素
lua_pop(m_state, 1);

我想将一些 C 函数导出到 Lua 中,但是在 Lua 中调用 RequestData 方法时,实际上是调用了 DataClient_Index 方法。那么为什么要使用索引方法而不是在 Lua 中使用特殊方法呢?

点赞
用户1008957
用户1008957

Lua 默认情况下在执行索引操作时不会查找元表。

  • 对于 tables,当表中不存在索引时才会触发 __index 元方法。
  • 对于 userdata,由于无法在 userdata 中存储键值对,因此始终会调用 __index

对于 userdata 对象,通常将 方法 放在元表中。为了实现这一点,__index 元表字段应该是元表本身,或者是一个尝试在元表中查找索引的函数。

如果选择第一种方法(最简单的方法),可以编写以下代码:

lua_State*  m_state;
luaL_newmetatable(m_state,LUA_DATACLIENT);

lua_pushvalue(m_state, -1); // 推入元表
lua_setfield(m_state,-2,"__index"); // __index 指向元表本身

// ...
2012-12-12 06:43:24