[英]attempt to call method 'print' (a nil value) when implementation OOP in Lua
So, I'm trying to write a simple class in Lua for representing CSV fields: 因此,我试图在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
But when I try to use this class like this: 但是当我尝试像这样使用此类时:
c = csv_entry.create("Volvo", 10000, "Eric")
c:print() -- line 25
I get the error message 我收到错误消息
lua: csv.lua:25: attempt to call method 'print' (a nil value)
And I can't really figure out the issue here. 而且我真的无法在这里找出问题。 What am I doing wrong?
我究竟做错了什么?
You probably meant to do is this: 您可能打算这样做:
function csv_entry.create(...)
return setmetatable(arg, csv_entry)
end
Your posted version of cvs_entry.create
just returns it's arguments packed into a table, so this code: 您发布的
cvs_entry.create
版本仅返回打包在表中的参数,因此此代码:
c = csv_entry.create("Volvo", 10000, "Eric")
c:print()
Is exactly equivalent to this code: 完全等同于以下代码:
c = {"Volvo", 10000, "Eric"}
c:print()
c
doesn't contain a print
entry, so c.print
returns nil
and c:print()
fails because you're trying to "call" nil
. c
不包含print
条目,因此c.print
返回nil
而c:print()
失败,因为您试图“调用” nil
。
Side note: the implicit arg
parameter to variadic functions was removed in Lua 5.1 (6 years ago). 旁注:Lua 5.1(6年前)中删除了可变参数函数的隐式
arg
参数。 The correct way to do this now is: 现在执行此操作的正确方法是:
function csv_entry.create(...)
local arg = {...}
return setmetatable(arg, csv_entry)
end
Or simply: 或者简单地:
function csv_entry.create(...)
return setmetatable({...}, csv_entry)
end
As long as we're here: you're going to get no output from csv_entry:tostring
because it doesn't return anything. 只要我们在这里,您就不会从
csv_entry:tostring
获得任何输出,因为它不会返回任何内容。 Also, if all you're trying to do is to concatenate a bunch of items with comma separators, you can use table.concat
: 另外,如果您要做的就是用逗号分隔符连接一堆项目,则可以使用
table.concat
:
function csv_entry:tostring()
return table.concat(self, ', ')
end
I rewrite your code to meet what it is for, it runs OK for me: 我重写您的代码以满足其用途,它对我来说运行正常:
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()
Like @Mud said, the create(...) in your code is just a regular call and returns all arguments from ..., if you want csv_entry works like a class, then you have to put codes which set metatable and __index into create(...), and return an instance from csv_entry class 就像@Mud所说的那样,代码中的create(...)只是一个常规调用,它从...返回所有参数,如果要使csv_entry像一个类一样工作,则必须将设置metatable和__index的代码放入create(...),然后从csv_entry类返回一个实例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.