Lua表,最简单的方法来重载__tostring

感谢所有讨论如何自定义打印表的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()
  -- 可以在子类中自定义
  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}
点赞
用户646619
用户646619

这是最简单的方法吗?

远远不是。最简单的方法是在你的元表中添加一个__tostring函数。

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

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

这不是一个问题。一个类应该只有一个元表,一个表中的一个条目的内存使用是可以忽略不计的。

覆盖 tostring 既丑陋又潜在危险:如果你(或其他人)正在使用一个拥有具有副作用的 s 方法的库,将会怎样?

2016-02-10 23:22:37