Index Table 用的下一個元方法

lua-users home
wiki

__index 是 Table 時重新撰寫 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

另見


RecentChanges · 偏好設定
編輯 · 歷程
上次編輯時間為 2007 年 5 月 28 日晚上 10:40 (格林威治標準時間) (差異)