Lua 中有没有一种方法可以知道数组中是否添加或删除了键值对?

local t = {}
local mt = setmetatable({
        -- 一些元方法,用于判断键值对何时被添加或丢失并打印消息
      }, t)

是否有一种方法可以做到这一点?我和某人谈论过这个问题,他们说我不能仅用元方法,还需要使用代理,但我对如何使其工作有点困惑。有人能帮忙吗?

谢谢

点赞
用户3342050
用户3342050
local tab = {}
local meta = {}

setmetatable(tab, {
  __newindex = function(self, key, value)
    print(key, value)
    rawset(self, key, value)
  end
})

tab[1] = 'this'
tab[#tab + 1] = 'that'
tab.the = 'other'
tab[3] = nil
tab[4] = 2

tab[1] = 'this'

tab[#tab + 1] = 'that'

tab.the = 'other'

tab[3] = nil

tab[4] = 2

2020-11-14 14:58:54
用户12918181
用户12918181

为了在lua中跟踪表的键,其中最重要的 metatable 键有两个:__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,因为原始表始终为空。

2020-11-14 15:01:54