索引表的下一次元方法

lua-users home
wiki

__index 是一个表时,重写 next()

要创建一个与这种索引方法匹配的 next() 函数(包括较低级别键对较高级别键的遮蔽),可以使用以下代码...

function tnext(t,o)
  local i,v

  if o then
    -- 'o' is not nil (it is a real existing key).
    -- Locate the key's table.
    local r = t
    while not rawget(r,o) do
      local m = getmetatable(r)
      r = m and m.__index
      assert(type(r)=="table", "Key not in table")
    end

    -- Grab the next non-shadowed index
    local s
    i = o -- Start with the current index.
    repeat
      -- Get next real (non-nil) index.
      i,v = next(r,i)
      while (i==nil) do
        local m = getmetatable(r)
        r = m and m.__index
        if (r==nil) then return nil,nil end -- None left.
        assert(type(r)=="table", "__index must be table or nil")
        i,v = next(r)
      end
      -- Find the next index's level.
      s = t
      while not rawget(s,i) do
        local m = getmetatable(s)
        s = m and m.__index
      end
      -- If match then not shadowed, else repeat.
    until (r==s)
    -- Return it.
    return i,v

  else
    -- 'o' is nil, so want the first real key. Scan each table in
    -- turn until we find one (or give up if all are empty).
    while t do
      i,v = next(t)
      if i then break end
      local m = getmetatable(t)
      t = m and m.__index
      assert(t==nil or type(t)=="table", "__index must be table or nil")
    end
    return i,v
  end
end

示例用法

t = {a=111,  b=222, c=333}
u = {a=123, d=444}
setmetatable(t, {__index=u})
for i,v in tnext,t do print(i,v) end
将给出以下结果
a  111
b  222
c  333
d  444

-- PeterHill

另请参阅


最近更改 · 偏好设置
编辑 · 历史记录
最后编辑于 2007 年 5 月 28 日下午 10:40 GMT (差异)