2017-12-29 12 views
2

要素が追加されたときにサイジングを自動的に追跡するメタテーブルを使用してカスタムテーブルを作成しました。それは非常にうまく動作し、#演算子またはgetn関数の必要性を取り除きます。table.insertは__indexをトリガーしませんか?

ただし、問題があります。 table.insertを呼び出すと、関数は明らかに__indexまたは__newindexを呼び出すことはありません。したがって、私のテーブルは、いつ要素がこのように削除されるかを知ることができません。私は問題がtable.removeと同じであると仮定します。

どのようにいずれかのことができます。

  • insertのイベントをキャプチャし、その
  • insertが私のテーブルの上に呼び出された場合、エラーをスロー行うには自分自身の関数を使用します。

あなたは__newindexでK、Vを印刷する場合は、そのkはtable.insertはどこ値を挿入するために見つけるために、テーブルのサイズを要求するので、これは常に1であるおかげ

function Table_new() 
    local public = { } 
    local tbl = { } 
    local size = 0 

    function public.size() 
     return size 
    end 

    return setmetatable(public, { 
     __newindex = function(t, k, v) 
      local previous_v = tbl[k] 
      rawset(tbl, k, v) 

      if previous_v ~= nil then 
       if v == nil then 
        size = size - 1 
       end 
      elseif v ~= nil then 
       size = size + 1 
      end 
     end, 

     __index = tbl 
    }) 
end 

local t = Table_new() 
t[5] = "hi" 
t[17] = "hello" 
t[2] = "yo" 
t[17] = nil 
print(t.size()) -- prints 2 

local z = Table_new() 
table.insert(z, "hey") 
table.insert(z, "hello") 
table.insert(z, "yo") 
print(z.size()) -- prints 1 -- why? 
+0

@lhf申し訳ありませんが私の例を再入力したとき、私は間違いを犯しました。私は問題を持っていて、hahaが存在しない変数を参照していない私の質問を更新しました。 – Hatefiend

+0

Lua 5.1ではプログラムは '1'ではなく' 0'を出力します。 –

+0

@EgorSkriptunoffそれは変です。この例では[Luaのデモサイト](https://i.imgur.com/L8xrmmO.png)で通訳を使っていました。それはなぜ異なった結果を印刷するのですか? [あなたは正しいですが](https://i.imgur.com/FnAPt1E.png)。なぜか分からない。 – Hatefiend

答えて

1

が表示されます。デフォルトでは、それは最後です。 __lenメタメソッドを追加する必要があります。しかしおそらく、これはあなたの目的を破ります(私にはあいまいです)。

+0

残念ながら私はLua 5.1上にあり、 '__len'や'# 'へのアクセス権はありません。その他の回避策がありますか? – Hatefiend

+0

実際には、テーブルに要素がないと見なすので、常にキーとして「1」が得られると思いますので、インデックス '1'に入れようとします。しかし、 'public'の代理テーブルはまだ' 1'のサイズを持っていますので、 '1'に再び挿入しようとしていますか?これはあなたが話していたサイクルですか? – Hatefiend

関連する問題