在 Lua 中实现面向对象编程时,出现“尝试调用方法 'print'(空值)”的错误。

因此,我正在尝试编写一个简单的 Lua 类来表示 CSV 字段:

csv_entry = {}
csv_entry.__index = csv_entry

function csv_entry.create(...)
   return arg
end

function csv_entry:tostring()
   local str = string.char()
   for i,v in ipairs(self) do
      if i < #self then
     str = str .. v
      else
     str = str .. v .. ", "
      end
   end
end

function csv_entry:print()
   print(self:tostring())
end

但是当我尝试像这样使用这个类时:

c = csv_entry.create("Volvo", 10000, "Eric")
c:print() -- line 25

我收到错误信息

lua: csv.lua:25: attempt to call method 'print' (a nil value)

我无法真正弄清楚问题所在。我做错了什么?

点赞
用户501459
用户501459

你可能想要做的是这样的:

function csv_entry.create(...)
   return setmetatable(arg, csv_entry)
end

你发布的版本中 cvs_entry.create 只是将它的参数打包到一个表中,所以这段代码:

c = csv_entry.create("Volvo", 10000, "Eric")
c:print()

与这段代码完全等价:

c = {"Volvo", 10000, "Eric"}
c:print()

c 不包含 print 项,因此 c.print 返回 nilc:print()失败,因为你试图"调用" nil


附注:在 Lua 5.1 中,有默认的可变参数函数 arg 已被移除(已有 6 年)。现在正确的方法是:

function csv_entry.create(...)
    local arg = {...}
    return setmetatable(arg, csv_entry)
end

或者简单地:

function csv_entry.create(...)
   return setmetatable({...}, csv_entry)
end

只要我们在这里:从 csv_entry:tostring 中得不到任何输出,因为它没有返回任何东西。此外,如果你所要做的仅仅是将一堆条目连接起来,使用逗号分隔符,你可以使用 table.concat

function csv_entry:tostring()
    return table.concat(self, ', ')
end
2012-06-06 21:47:10
用户1282919
用户1282919
csv_entry = {}

function csv_entry:create(...)
    o = {content = {}}
    self.__index = self;
    setmetatable(o, self)
    for i = 1, arg.n do
        o.content[i] = arg[i];
    end
    return o;
end

function csv_entry:tostring()
    local resStr = ""
    for i, v in pairs(self.content) do
      resStr = resStr .. v;
      if i < #(self.content) then
          resStr = resStr .. ", "
      end
    end
    return resStr;
end

function csv_entry:print()
    print(self:tostring())
end

c = csv_entry:create("Volvo", 10000, "Eric")
c:print()

像 @Mud 说的那样,你代码中的 create(...) 只是一个普通调用,并返回所有来自...的参数,如果你想让 csv_entry 能像一个类一样工作,那么你必须将设置元表和 __index 的代码放入 create(...) 中,同时从 csv_entry 类中返回一个实例。

2014-03-27 06:03:10