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

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

##元表的__index方法和__newindex方法

###1 使用__index方法的代码:

 1--[[
 2Lua中访问table的元素是先通过__index元方法来查找是否有这个函数,如果没有则返回nil。可以通过改变__index元方法,能够
 3改变检索之后的结果。__index的值可以直接是一个table,可以是一个function。如果是table则以该table作为索引进行查询,
 4如果是function,则以table和缺少的table的元素键值的key为参数、
 5--]]
 6Window = {}
 7Window.mt = {}
 8Window.prototype = {x = 0, y = 0, width=100, height = 100}
 9
10--[[
11参数1是table,参数2是key,这是固定的格式
12--]]
13Window.mt.__index = function(table, key)
14    return Window.prototype[key]
15end
16
17function Window.new(t)
18    setmetatable(t, Window.mt) -- 设置某个表t的元表为Window.mt
19    return t
20end
21
22-- 测试
23t = {x = 10, y = 20}
24w = Window.new(t)
25--[[
26表w就是表t,并且t的元表就是Window.mt。本来表t是没有“height”这一个元素项,但因为t指定了元表为Window.mt。
27而Window.mt又对元方法__index进行了改写,所以t.height就是Window.prototype.width。如果t本身已经有"height"的话
28那么t.height就不是Window.prototype.width了。
29--]]
30print(w.height)

###2 使用了__newindex方法的代码

 1Window = {}
 2Window.mt = {}
 3--[[
 4和__index方法相比,其函数参数多了一个值value,也就是说,如果某个指定的元素项在table中不存在,而又
 5调用了设置该元素项的值的时候,就会调用__index方法
 6--]]
 7Window.mt.__newindex = function(table, key, value)
 8    print("update of element" .. tostring(key) .. tostring(value))
 9    rawset(table, key, value) --[[ 这里必须用一个rawset函数去给一个在元表中不存在的元素项去赋值,而不能直接地用
10                                   table[key] = value的方式去赋值,因为table中key原本就不存在,直接设置的话会
11                                   再次引发元表的__newindex操作,变成不断递归的死循环,直至overflow
12                              --]]
13    --table[key] = value
14end
15
16function Window.new(t)
17    setmetatable(t, Window.mt)
18    return t
19end
20
21-- 测试
22t = {x=10,y=20}
23w = Window.new(t)
24w.x = 20   -- 表t的元素项x是存在的,所以直接设置元素项的值为10
25w.a = 10   -- 表t
26print(w.a)