【问题标题】:Lua table->address and address->tableLua表->地址和地址->表
【发布时间】:2013-07-20 14:28:45
【问题描述】:

想象一下下面的代码:

Mytable={}
print(Mytable)

打印类似Table: 12345 的内容。 如何在不弄乱tostring 的返回值的情况下从 Lua 中获取“地址”部分,更重要的是,如何取回表格?

在代码中:

addr=table2address(Mytable)
-- type(addr) is number, addr is 12345
Othertable=address2table(addr)
-- type(Othertable) is table, Othertable==Mytable is true (same reference)

有没有办法在 Lua 中实现这两个功能?如果没有,(如何)在 C 中执行此操作?

编辑:table2address 可以通过从 tostring(Mytable) 中删除 Table: 来完成,但前提是未定义元方法 __tostring,所以我想避免这种情况。

【问题讨论】:

  • 你为什么需要这个?
  • @nonchip 正如您在@DougCurrie 的回答中所见,表(或除nil 之外的任何值)可以用作表键。这几乎可以满足您所要求的所有需求。你有特殊情况吗?

标签: pointers lua lua-table


【解决方案1】:

一个简单的实现满足你的所有标准,但一个:

function table2address(Mytable) return Mytable end
function address2table(addr) return addr end

演示:

> Mytable={}
> print(Mytable)
table: 0x7fe511c0a190
> addr = table2address(Mytable)
> Othertable=address2table(addr)
> =type(Othertable)
table
> print(Othertable==Mytable)
true

稍微复杂一点的实现符合您的所有标准:

t2at = {}

function table2address(Mytable) 
  local addr = t2at[Mytable]
  if addr == nil then
    addr = #t2at + 1
    t2at[Mytable] = addr
    t2at[addr] = Mytable
  end
  return addr
end

function address2table(addr)
  return t2at[addr]
end

演示:

> Mytable={}
> addr = table2address(Mytable)
> Othertable=address2table(addr)
> =type(Othertable)
table
> print(Othertable==Mytable)
true
> =type(addr)
number

那么,为什么地址对您很重要?

在像 Lua 这样的垃圾收集语言中,只能保存对对象的引用,而不是地址。 [目前的实现可能会或可能不会在 GC 期间移动对象,但除了 userdata 和 Lua 声明之外,Lua 有权移动任何东西。]

附录

Re:“地址永远不会随机化(在 2 个新的交互式 lua 实例中尝试 print({}))”

e$ lua
Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print({})
table: 0x7fdaca4098c0
> ^D
e$ lua
Lua 5.2.2  Copyright (C) 1994-2013 Lua.org, PUC-Rio
> print({})
table: 0x7fb02a4098c0
> ^D
e$ 

Re: 确实需要物理地址

查看实现打印内容的函数luaL_tolstring;它有(在 Lua 5.2.2 中):

  default:
    lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
                                        lua_topointer(L, idx));
    break;

所以,lua_topointer(L, idx) 是获取表地址所需的函数。

【讨论】:

  • +1 干得好!符合规定的标准,同时避免实施细节。
  • 很抱歉,但您的两种方法都不符合标准:第一种方法是个坏笑话,只是返回输入。第二个实现了一个数字自动增长的查找表。这些甚至都不看表的地址。
  • 回答你的问题:地址对我来说很重要,因为它显然可以从 lua 中获取(参见 tostring),所以它存在并且可以用来引用表格。由于地址永远不会随机化(在 2 个新的交互式 lua 实例中尝试 print({})),它们可用于独立处理同一个表。我知道这不可靠,但是当我试图实现一些类似 freezercode 的功能作为技术演示时,我们鼓励用户尝试这些值。
  • 换句话说:我知道那里有许多列表/数组/任何实现,所以地址确实是唯一重要的事情,因为我不想要任何列表/查找表/.. . 但只是一个窥视/戳等效功能。
  • @nonchip,请参阅我针对您的 cmets 的附录。
猜你喜欢
  • 2016-04-08
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
相关资源
最近更新 更多