《Cocos2d-x之lua核心编程(第二版)》示例代码注释详解 2


请尊重原作者的工作,转载时请务必注明转载自:www.xionggf.com

元表的index方法和newindex方法

1 使用__index方法的代码:

--[[
Lua中访问table的元素是先通过__index元方法来查找是否有这个函数,如果没有则返回nil。可以通过改变__index元方法,能够
改变检索之后的结果。__index的值可以直接是一个table,可以是一个function。如果是table则以该table作为索引进行查询,
如果是function,则以table和缺少的table的元素键值的key为参数、
--]]
Window = {}
Window.mt = {}
Window.prototype = {x = 0, y = 0, width=100, height = 100}

--[[
参数1是table,参数2是key,这是固定的格式
--]]
Window.mt.__index = function(table, key)
    return Window.prototype[key]
end

function Window.new(t)
    setmetatable(t, Window.mt) -- 设置某个表t的元表为Window.mt
    return t
end

-- 测试
t = {x = 10, y = 20}
w = Window.new(t)
--[[
表w就是表t,并且t的元表就是Window.mt。本来表t是没有“height”这一个元素项,但因为t指定了元表为Window.mt。
而Window.mt又对元方法__index进行了改写,所以t.height就是Window.prototype.width。如果t本身已经有"height"的话
那么t.height就不是Window.prototype.width了。
--]]
print(w.height)

2 使用了__newindex方法的代码

Window = {}
Window.mt = {}
--[[
和__index方法相比,其函数参数多了一个值value,也就是说,如果某个指定的元素项在table中不存在,而又
调用了设置该元素项的值的时候,就会调用__index方法
--]]
Window.mt.__newindex = function(table, key, value)
    print("update of element" .. tostring(key) .. tostring(value))
    rawset(table, key, value) --[[ 这里必须用一个rawset函数去给一个在元表中不存在的元素项去赋值,而不能直接地用
                                   table[key] = value的方式去赋值,因为table中key原本就不存在,直接设置的话会
                                   再次引发元表的__newindex操作,变成不断递归的死循环,直至overflow
                              --]]
    --table[key] = value
end

function Window.new(t)
    setmetatable(t, Window.mt)
    return t
end

-- 测试
t = {x=10,y=20}
w = Window.new(t)
w.x = 20   -- 表t的元素项x是存在的,所以直接设置元素项的值为10
w.a = 10   -- 表t
print(w.a)