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)