加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

lua __index __newindex upvalue 示例

发布时间:2020-12-14 22:18:33 所属栏目:大数据 来源:网络整理
导读:项目中有个公会对象,数据大部分存在data中,之前都是 u.data.point这样访问,太麻烦了。 于是通过设置__index 使之可以直接访问属性,u.point。 但是还是不能直接改属性,u.point = 4,所以再设置了__newindex。 ? 在设置了setmetatable之后,不能直接给u添

项目中有个公会对象,数据大部分存在data中,之前都是 u.data.point这样访问,太麻烦了。

于是通过设置__index 使之可以直接访问属性,u.point。

但是还是不能直接改属性,u.point = 4,所以再设置了__newindex。

?

在设置了setmetatable之后,不能直接给u添加新属性,因为设置了__newindex,新的属性将直接加到u.data中的。

?

[c-sharp] view plain copy print ?
  1. Union?=?{??
  2. ????data?=?nil,??
  3. ????dirty?=?nil,??
  4. }??
  5. ---?生成新的对象??
  6. function?Union:new(o)??
  7. ????o?=?o?or?{}??
  8. ????setmetatable(o,self)??
  9. ????self.__index?=?self??
  10. ????return?o??
  11. end??
  12. ---?初始化Union数据??
  13. function?Union:init(data)??
  14. ????self:initTable()??
  15. ????self.data?=?data??
  16. ????local?meta?=?{}??
  17. ????meta.__index?=?function?(table,?key)??
  18. ????????if?Union[key]?~=?nil?then??
  19. ????????????return?Union[key]??
  20. ????????else??
  21. ????????????return?self.data[key]??
  22. ????????end??
  23. ????end??
  24. ????meta.__newindex?=?function(table,key,?value)??
  25. ????????self.data[key]?=?value??
  26. ????end??
  27. ????setmetatable(self,?meta)??
  28. end??
  29. function?Union:initTable()??
  30. ????if?self.data?==?nil?then??
  31. ????????self.data?=?{}??
  32. ????end??
  33. ????if?self.dirty?==?nil?then??
  34. ????????self.dirty?=?{}??
  35. ????end??
  36. end??
  37. function?Union:print()??
  38. ????print(self.point,?self.data.point)??
  39. end??
  40. function?pt()??
  41. ????print(data1.point,?data2.point,?u.point,?u.data.point)??
  42. end??
  43. u?=?Union:new()??
  44. data1?=?{point?=?3}??
  45. data2?=?{point?=?103}??
  46. u:init(data1)??
  47. pt()??
  48. u.point?=?4??
  49. pt()??
  50. u.data?=?data2??
  51. pt()??
  52. u.point?=?104??
  53. pt()??

?

?

?

通过修改__index和__newindex会获得不同的结果。

?

1.正确结果

[c-sharp] view plain copy print ?
  1. function?Union:init(data)??
  2. ????self:initTable()??
  3. ????self.data?=?data??
  4. ????local?meta?=?{}??
  5. ????meta.__index?=?function?(table,?meta)??
  6. 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 ?
  1. function?Union:init(data)??
  2. ????self:initTable()??
  3. ????self.data?=?data??
  4. ????local?meta?=?{}??
  5. ????meta.__index?=?function?(table,?key)??
  6. ????????if?Union[key]?~=?nil?then??
  7. ????????????return?Union[key]??
  8. ????????else??
  9. ????????????return?self.data[key]??
  10. ????????end??
  11. ????end??
  12. ????meta.__newindex?=?self.data??
  13. ????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 ?
    1. function?Union:init(data)??
    2. ????self:initTable()??
    3. ????self.data?=?data??
    4. ????local?meta?=?{}??
    5. ????meta.__index?=?function?(table,?key)??
    6. ????????if?Union[key]?~=?nil?then??
    7. ????????????return?Union[key]??
    8. ????????else??
    9. ????????????return?data[key]??
    10. ????????end??
    11. ????end??
    12. ????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指向的是什么对象

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读