0

だから、私はCSVフィールドを表すためにLuaで簡単なクラスを書こうとしています:

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)

そして、私はここで問題を本当に理解することはできません。私は何が間違っているのですか?

4

2 に答える 2

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()

cprintエントリが含まれていないため、「呼び出し」を試みているためc.printに戻りnilc:print()失敗しますnil


補足:arg可変個引数関数への暗黙のパラメーターは、Lua 5.1(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-06T21:47:10.670 に答える
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をクラスのように機能させる場合は、メタテーブルと__indexを設定するコードをに配置する必要があります。 create(...)、およびcsv_entryクラスからインスタンスを返します

于 2014-03-27T06:03:10.613 に答える