Есть ли способ узнать, добавлен или удален ключ из массива в lua?

local t = {}
local mt = setmetatable({
        -- some meta method to know when a key is added or lost and prints a message
      }, t)

Есть ли способ сделать это. Я говорил об этом с кем-то, и они сказали, что я не могу делать это только с мета-методами, но и с прокси. Я немного озадачен тем, как это сделать. Кто-нибудь может помочь?

Спасибо


person baked    schedule 14.11.2020    source источник


Ответы (2)


Для отслеживания ключей таблицы в lua есть 2 наиболее важных ключа в метатаблице: __index и __newindex.

__newindex используется для создания нового ключа в таблице, если такой ключ не найден. __index используется для получения значения, если такого ключа в таблице нет.

С __newindex можно отслеживать создание, но не присвоение, поэтому невозможно отследить удаление ключа:

<script src="https://github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js"></script>
<script type="application/lua">

local t={}
setmetatable(t, {
  __newindex = function(self, key, value)
    print('Added Key:'..key,'Value:'..value)
    rawset(self, key, value)
  end
})

t.test = 'test'
t.test = nil -- delete not tracked
t.test = 'test2'

</script>

Используя прокси-таблицу и __newindex с __index, мы можем отслеживать каждое назначение:

<script src="https://github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js"></script>
<script type="application/lua">

local t={}
local proxytable={}
setmetatable(t, {
  __newindex = function(self, key, value)
    if proxytable[key] then
      if value == nil then
        print('Deleted Key:'..key)
      else
        print('Changed Key:'..key,'Value:'..value)
      end
    else
      print('Added Key:'..key,'Value:'..value)
    end
    rawset(proxytable, key, value)
  end,
  __index = proxytable
})

t.test = 'test'
t.test = nil
t.test = 'test2'
t.test = 'test3'
t.test = nil

</script>

Если вы хотите перечислить ключи таблицы с помощью pairs(), ipairs(), вам нужно использовать метаключи __pairs и __ipairs, поскольку исходная таблица всегда пуста.

person Darius    schedule 14.11.2020
comment
Спасибо!! Это сработало!! Я был в этом в течение длительного времени. - person baked; 14.11.2020

person    schedule
comment
да, я знал предпосылку, просто следил за текстом с -- tutorialspoint.com/lua/lua_metatables. htm -- и у них были ненужные кавычки вокруг значения. То же самое. - person Doyousketch2; 14.11.2020
comment
Это работает только для вставки, но не для удаления. - person DarkWiiPlayer; 17.11.2020