项目中有个公会对象,数据大部分存在data中,之前都是 u.data.point这样访问,太麻烦了。
于是通过设置__index 使之可以直接访问属性,u.point。
但是还是不能直接改属性,u.point = 4,所以再设置了__newindex。
?
在设置了setmetatable之后,不能直接给u添加新属性,因为设置了__newindex,新的属性将直接加到u.data中的。
?
[c-sharp]
view plain
copy
print
?
- Union?=?{??
- ????data?=?nil,??
- ????dirty?=?nil,??
- }??
- ---?生成新的对象??
-
function?Union:new(o)??
- ????o?=?o?or?{}??
- ????setmetatable(o,self)??
- ????self.__index?=?self??
-
????return?o??
- end??
- ---?初始化Union数据??
- function?Union:init(data)??
- ????self:initTable()??
- ????self.data?=?data??
- ????local?meta?=?{}??
- ????meta.__index?=?function?(table,?key)??
-
????????if?Union[key]?~=?nil?then??
-
????????????return?Union[key]??
-
????????else??
-
????????????return?self.data[key]??
- ????????end??
- ????end??
- ????meta.__newindex?=?function(table,key,?value)??
- ????????self.data[key]?=?value??
- ????end??
- ????setmetatable(self,?meta)??
- end??
- function?Union:initTable()??
-
????if?self.data?==?nil?then??
- ????????self.data?=?{}??
- ????end??
-
????if?self.dirty?==?nil?then??
- ????????self.dirty?=?{}??
- ????end??
- end??
- function?Union:print()??
- ????print(self.point,?self.data.point)??
- end??
- function?pt()??
- ????print(data1.point,?data2.point,?u.point,?u.data.point)??
- end??
-
u?=?Union:new()??
- data1?=?{point?=?3}??
- data2?=?{point?=?103}??
- u:init(data1)??
- pt()??
- u.point?=?4??
- pt()??
- u.data?=?data2??
- pt()??
- u.point?=?104??
- pt()??
?
?
?
通过修改__index和__newindex会获得不同的结果。
?
1.正确结果
[c-sharp]
view plain
copy
print
?
- function?Union:init(data)??
- ????self:initTable()??
- ????self.data?=?data??
- ????local?meta?=?{}??
- ????meta.__index?=?function?(table,?meta)??
- end??
3??? 103??? 3??? 3 4??? 103??? 4??? 4 4??? 103??? 103??? 103 4??? 104??? 104??? 104
?
2.错误的__newindex
[c-sharp]
view plain
copy
print
?
- function?Union:init(data)??
- ????self:initTable()??
- ????self.data?=?data??
- ????local?meta?=?{}??
- ????meta.__index?=?function?(table,?key)??
-
????????if?Union[key]?~=?nil?then??
-
????????????return?Union[key]??
-
????????else??
-
????????????return?self.data[key]??
- ????????end??
- ????end??
- ????meta.__newindex?=?self.data??
- ????setmetatable(self,key)
if Union[key] ~= nil then
return Union[key]
else
return self.data[key]
end
end
meta.__newindex = self.data
setmetatable(self,meta)
end
3??? 103??? 3??? 3 4??? 103??? 4??? 4 4??? 103??? 103??? 103 104??? 103??? 103??? 103
3.错误的__index
[c-sharp]
view plain
copy
print
?
- function?Union:init(data)??
- ????self:initTable()??
- ????self.data?=?data??
- ????local?meta?=?{}??
- ????meta.__index?=?function?(table,?key)??
-
????????if?Union[key]?~=?nil?then??
-
????????????return?Union[key]??
-
????????else??
-
????????????return?data[key]??
- ????????end??
- ????end??
- ????meta.__newindex?=?function(table,key)
if Union[key] ~= nil then
return Union[key]
else
return data[key]
end
end
meta.__newindex = function(table,meta)
end
3??? 103??? 3??? 3 4??? 103??? 4??? 4 4??? 103??? 4??? 103 4??? 104??? 4??? 104
?对象A在内部可以修改HP.外部对象只能访问对象A的HP,不能修改.
这东西其实可以用__index和__newindex来实现.
__index指向对象A,这样就可以访问;
__newindex重写,修改hp的话,就禁止.就可以完成他的需求.
下面给出简单的代码:
function cannotModifyHp(object)
????
local proxy = {}
????
local mt = {
????????
__index = object,
????
__newindex = function(t,k,v)
????????
if
k ~=
"hp"
then
????????
object[k] = v
????????
end
????
end
????
}
????
setmetatable(proxy,mt)
????
return
proxy
end
? ?
object = {hp = 10,age = 11}
function object.sethp(self,newhp)
????
self.hp = newhp
end
? ?
o = cannotModifyHp(object)
? ?
o.hp = 100
print(o.hp)
? ?
o:sethp(111)
print(o.hp)
? ?
object:sethp(100)
print(o.hp)
|
function cannotModifyHp(object)
????
local proxy = {}
????
local mt = {
????????
__index = object,
????
__newindex = function(t,v)
????????
if
k ~=
"hp"
then
????????
object[k] = v
????????
end
????
end
????
}
????
setmetatable(proxy,mt)
????
return
proxy
end
object = {hp = 10,age = 11}
function object.sethp(self,newhp)
????
self.hp = newhp
end
? ?
o = cannotModifyHp(object)
? ?
o.hp = 100
print(o.hp)
? ?
o:sethp(111)
print(o.hp)
? ?
object:sethp(100)
print(o.hp)
?
这里影响程序的不同结果是upvalue导致的。
由于一般程序中有可能动态改data。所以建议用function设置__index和__newindex,尤其注意各个不同函数中self指向的是什么对象
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|