所以,我正在尝试在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)
我无法在这里找出问题所在。我做错了什么?
答案 0 :(得分:3)
你可能打算这样做:
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
返回nil
而c:print()
失败,因为您正在尝试“呼叫”{{ 1}}。
旁注:Lua 5.1(6年前)中删除了对可变参数函数的隐式nil
参数。现在正确的做法是:
arg
或者简单地说:
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
答案 1 :(得分:0)
我重写你的代码以满足它的目的,它对我来说运行正常:
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像一个类一样工作,那么你必须放置设置metatable的代码和__index到create(...),并从csv_entry类返回一个实例