【问题标题】:lua tables, simplest way to overload __tostringlua 表,重载 __tostring 的最简单方法
【发布时间】:2016-02-10 23:07:27
【问题描述】:

感谢所有讨论如何自定义打印表的 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}

【问题讨论】:

  • 为什么要覆盖 tostring 而不是设置 __tostring 元方法?
  • 我投票决定将此问题作为离题结束,因为它显示了一个有效的颂歌,并且 OP 要求Code Review
  • @hjpotter92 工作代码 在 Stack Overflow 上不是有效的离题原因。他要求改进特定问题/问题。无论如何,这与代码审查无关

标签: lua tostring metatable


【解决方案1】:

这是最简单的方法吗?

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

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

不会为每个对象的元表添加大小。

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

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

【讨论】:

  • 请注意,Lua 5.1 中的__tostring 不会影响对lua_tolstring 的调用。这已在 5.2 及更高版本中修复
猜你喜欢
  • 2012-10-03
  • 1970-01-01
  • 2013-09-24
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 2014-12-01
  • 2010-10-27
相关资源
最近更新 更多