【问题标题】:get the address of a lua object获取 lua 对象的地址
【发布时间】:2022-04-14 01:43:17
【问题描述】:

当你在 lua 中打印某些类型(例如函数和表)时,你会得到类型的名称和地址,如下所示:

> tab = {}
> print(tab)
table: 0xaddress

我创建了一个简单的类,如下所示,我想类似地重写__tostring 方法。如何获取要打印的对象的地址?

这是我的课。我希望print(pair) 打印出Pair: 0xaddress。显然这是一个微不足道的例子,但这个概念很有用:

Pair = {}
Pair.__index = Pair

function Pair.create()
 local p = {}
 setmetatable(p, Pair)
 p.x = 0
 p.y = 0
 return p
end

function Pair:getx()
 return self.x
end

function Pair:gety()
 return self.y
end

function Pair:sety(iny)
 self.y=iny   
end

function Pair:setx(inx)
 self.x=inx
end

【问题讨论】:

    标签: printing lua


    【解决方案1】:

    这里有一个很老套的方法:

    Pair.__tostringx = function (p)
        Pair.__tostring = nil    
        local s = "Pair " .. tostring(p)                                                                                                                                                                                                    
        Pair.__tostring = Pair.__tostringx
        return s
    end
    Pair.__tostring = Pair.__tostringx    
    
    > print(p)
    Pair table: 0x7fe469c1f900
    

    您可以在Pair.__tostringx 中进行更多的字符串操作以获得您想要的格式,例如,删除“table”。

    【讨论】:

    • +1 因为这行得通,但如果 Lua 有一个 rawtostring 函数来避免这种黑客攻击,那就太好了。
    【解决方案2】:

    我认为打印table: 0xaddress__tostring() 实际上并没有在直接Lua 中实现。我环顾了一堆,但我能想到的唯一方法并不完全是你的想法。我在 Pair 类中添加了一个名为 toString 的函数,它使用默认的__tostring() 来获取普通字符串,然后取出“table”并放入“Pair”。

    function Pair:toString()
        normalPrint = tostring(self)
        return ("Pair:" .. normalPrint:sub(7))
    end
    
    pair = Pair.create()
    print(pair:toString())
    

    然后调用 Pair:toString() 来获得正确格式的输出。在覆盖 __tostring 时不能这样做,因为您将很难访问 super 的 __tostring,并且如果您调用 Pair 的 __tostring,则递归会发生堆栈溢出。

    【讨论】:

      【解决方案3】:

      与您使用的语法不同,但有效:(但可以改进)

      Pair = {}
      Pair.address = string.gsub(tostring(Pair), "table:", "") --Gets the original address as a string.
      local metas = {
          __tostring = function(tab)
              return "Pair:" .. tab.address
          end 
      }
      setmetatable(Pair, metas)
      print(Pair) --Will print Pair: 0xaddress
      

      【讨论】:

        【解决方案4】:

        您可以在 Lua 5.3 或更高版本中使用__name

        print(tostring(setmetatable({}, {__name = "Pair"})))
        

        打印出来:

        Pair: 0x5575ef88cf50
        

        【讨论】:

          【解决方案5】:
          local function f() end
          local t = {}
          
          print(f, t)
          print(string.format("%p\t%p", f, t))
          
          --[[
          function: 0x8813c0  table: 0x881810
          0x8813c0    0x881810
          ]]
          

          https://www.lua.org/demo.html 上测试。

          【讨论】:

            【解决方案6】:

            试试

            function rawstr(t)
              local mt = getmetatable(t)
              local save_tostring
              if mt and mt.__tostring then
                 save_tostring = mt.__tostring
                 mt.__tostring = nil
              end
              local raw = tostring(t)
              if save_tostring then
                mt.__tostring = save_tostring
              end
              return raw
            end
            

            【讨论】:

              猜你喜欢
              • 2018-10-19
              • 1970-01-01
              • 2016-06-14
              • 2015-03-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多