【问题标题】:Why push a duplicate key when adding to a table in Lua?在 Lua 中添加表时为什么要推送重复键?
【发布时间】:2010-07-23 02:28:58
【问题描述】:

我正在学习如何使用 Programming Gems 6(第 4.2 章)一书中的类型检查将 C++ 对象绑定到 Lua。对于类型检查,用户数据/字符串对存储在环境表中,代码给出了如何做到这一点:

void Binder::pushusertype(void* udata, const char* tname) {
 lua_pushlightuserdata(L, udata); // push address 
 lua_pushvalue(L, -1);    // duplicate address
 lua_pushstring(L, tname);  // push type name
 lua_rawset(L, LUA_ENVIRONMENTINDEX); // envtable[address] = tname
}

Binder 类有一个 Lua State 作为属性,命名为“L”

如您所见,地址被推送了两次。由于这一小段代码仅作为示例给出,因此推送到堆栈上的重复地址似乎不会用于此函数之外的任何目的,这让我相信这是有特定原因的。所以我的问题是,为什么要这样做?

【问题讨论】:

    标签: c++ lua


    【解决方案1】:

    你没有。

    lua_rawset 会将 tname 和副本从堆栈中弹出,但会将原始用户数据留在堆栈中。 我不确定它是否是拼写错误(看起来不太可能),我想以后可能需要它。 不知道书中是否还有更多内容,提到了这一点,但这就是代码的作用。

    【讨论】:

      【解决方案2】:

      这个函数做了两件事:

      它将一个 lightuserdata 对象推入堆栈,当函数返回时,它将位于 lua 堆栈位置 -1。它还使用存储在表键 address(等于 udata)中的名称 tname 更新当前函数环境。如果当前函数环境是正常的全局环境,则等效的 Lua 代码为:

      local x = <udata as lightuserdata>
      _G[x] = <tname>
      

      x 的一个副本用于做_G[x] = ... 的事情,另一个在函数返回时留在堆栈上(与以push 开头的函数的名称一致)。

      【讨论】:

        猜你喜欢
        • 2012-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-19
        • 1970-01-01
        • 2012-08-08
        • 2023-04-06
        • 2020-11-19
        相关资源
        最近更新 更多