3

感谢所有讨论如何自定义打印表的 Lua stackoverflow 人员。经过大量阅读,我发布以下内容并询问 Lua 大师......

  • 这是最简单的方法吗?
  • 是不是太简单了(即以某种我不理解的方式损坏)?

请注意以下事项:

  • 允许不打印的私有字段(只需以“_”开头的名称)
  • 不会增加metatable每个对象的大小。

我的方法重写了默认tostring方法。

_tostring =  _tostring or tostring
function tostring(t)
  if type(t) == "table" then 
    status, stuff = pcall(function() return t:s() end) 
    if status then 
      return stuff 
  end end 
  return _tostring(t) 
end

以上有点邪恶(对 pcall 的调用......不是我最自豪的代码,但是,嘿,它有效)。

无论如何,现在对我们可以使用以下自制对象系统定义的对象tostring进行方法调用:t:s()

Object={}

function Object:new(o)
   o = o or {} 
   setmetatable(o,self)  
   self.__index = self
   return o
end

这是 -- 的默认定义,:s()可以在子类中自定义。

function Object:s()
  -- can be customized in subclasses
  local out,sep="{",":"
  for x,y in pairs(self) do 
    if string.sub(x,1,1) ~= "_" then
      out = out..sep..x.." "..y 
      sep = " :"
  end end  
  return out .. '}'
end

例如

x=Object:new{a=1, _b=2};print(x)
{:a 1}
4

1 回答 1

11

这是最简单的方法吗?

到目前为止,没有。最简单的方法是将__tostring函数添加到您的元表中。

function MyClass:__tostring()
    return "<MyClass: "..self.foo..">"
end

不会将大小添加到每个对象的元表中。

这不是问题。每个类只能存在一个元表。表中一个条目的内存使用可以忽略不计。

覆盖tostring既丑陋又具有潜在危险:如果您(或其他人)使用的库的对象具有s具有副作用的方法怎么办?

于 2016-02-10T23:22:37.507 回答