GVKun编程网logo

lua __index __newindex upvalue 示例(lua __index和__newindex)

25

在本文中,我们将为您详细介绍lua__index__newindexupvalue示例的相关知识,并且为您解答关于lua__index和__newindex的疑问,此外,我们还会提供一些关于Lua--

在本文中,我们将为您详细介绍lua __index __newindex upvalue 示例的相关知识,并且为您解答关于lua __index和__newindex的疑问,此外,我们还会提供一些关于Lua -- __index元方法、lua --- __newindex 的使用规则、lua setmetatable __index __newindex、lua 之__index/__newindex的理解的有用信息。

本文目录一览:

lua __index __newindex upvalue 示例(lua __index和__newindex)

lua __index __newindex upvalue 示例(lua __index和__newindex)

项目中有个公会对象,数据大部分存在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()  
Union = { data = nil,dirty = nil,} --- <a href="https://www.jb51.cc/tag/shengcheng/" target="_blank">生成</a>新的对象 function Union:new(o) o = o or {} set<a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>table(o,self) self.__index = self return o end --- 初始化Union数据 function Union:init(data) self:initTable() self.data = data local <a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a> = {} <a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>.__index = function (table,key) if Union[key] ~= nil then return Union[key] else return self.data[key] end end <a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>.__newindex = function(table,value) self.data[key] = value end set<a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>table(self,<a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>) 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 ?
  1. function Union:init(data)  
  2.     self:initTable()  
  3.     self.data = data  
  4.     local Meta = {}  
  5.     Meta.__index = function (table, Meta)  
  6. end  
function Union:init(data) self:initTable() self.data = data local <a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a> = {} <a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>.__index = function (table,<a href="https://www.jb51.cc/tag/Meta/" target="_blank">Meta</a>) 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指向的是什么对象

总结

以上是小编为你收集整理的lua __index __newindex upvalue 示例全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

Lua -- __index元方法

Lua -- __index元方法

总结

以上是小编为你收集整理的Lua -- __index元方法全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

lua --- __newindex 的使用规则

lua --- __newindex 的使用规则

1、如果 __newindex 是一个函数,在给 table 不存在的字段赋值的时候,会调用这个函数
2.如果 __newindex 是一个table,在给 table 不存在的字段赋值的时候,会直接给 __newindex 的 table 赋值

测试用例:

 1 local Song = {name = "南山南"};
 2 
 3 local mt = 
 4 {
 5     __index = Song, 6     __newindex = function(table,key,val)
 7         print(key .. "是一个不存在的字段,不能对其赋值!");
 8     end
 9 };
10 
11 local animal = {}
12 setMetatable(animal,mt);
13 print(animal.name);
14 animal.name = "cat";  
15 
16 local tmp = {};
17 
18 local mt1 = 
19 {
20     __index = Song;
21     __newindex = tmp;
22 };
23 local animal1 = {};
24 setMetatable(animal1,mt1);
25 print(tmp.cat);
26 animal1.cat = "Cat";
27 print(tmp.cat);

编译结果:

分享图片

lua setmetatable __index __newindex

lua setmetatable __index __newindex

总结

以上是小编为你收集整理的lua setmetatable __index __newindex全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

lua 之__index/__newindex的理解

lua 之__index/__newindex的理解

--example:
local temp_table ={
	10,1,Index1 = "hello",Index2 = "world",Index3 = "lua",Index4 = "language",lang = "lua language",}

temp_table.__add = function(a,b) return 3 end


for _,Value in pairs(temp_table) do
	print(Value)
end

local temp_Metable_table = {
	Index1 = "temp_new_Metable_Index1",Index2 = "temp_new_Metable_Index2",Key = "temp_new_Metable_Key_end",}


for _,Metable_Value in pairs(temp_Metable_table) do
	print(Metable_Value)
end
--只能访问temp_table的方法
--setMetatable(temp_Metable_table,temp_table) --如果setMetable 为这种方式的话,那么我不能够对Metable进行原子操作
--print(temp_Metable_table + temp_table)

--如果是这种方式的话,我们只能访问它的原子,也就是它的数据成员
--[[setMetatable(temp_Metable_table,{__index = temp_table} ) 

print(temp_Metable_table[1])
print(temp_Metable_table["lang"])--]]

--如果是__newindex的话,我们可以访问原table,找到相关的key,除此之外,你还可以自己给原table添加数据成员
setMetatable(temp_Metable_table,{__newindex = temp_table} ) 
temp_Metable_table[5] = 100
print(temp_Metable_table[5])
print(temp_table[5])



Window = {}

Window.prototype = {x = 0,y = 0,width = 100,height = 100,}
Window.mt = {}
function Window.new(o)
	setMetatable(o,Window.mt)
	print(getMetatable(o))
	print(getMetatable(Window.mt))
	return o
end

Window.mt.__index = function (t,key) //由于__index 给赋予了funcion,一个匿名函数
	-- body
	return 1000
end

w = Window.new({x = 10,y = 20})
print(w.a) //在这里虽然没有a这个成员,但是会默认a为__index所绑定的function返回值作为a的值

Window = {}
Window.mt = {}

function Window.new(o)
	setMetatable(o,Window.mt)
	return o
end
Window.mt.__index = function (t,key)
	return 1000
end
Window.mt.__newindex = function (table,key,value)
	if key == "wangbin" then
		rawset(table,"wangbin","yes,i am")
	end
end
w = Window.new{x = 10,y = 20}
w.wangbin = "55"
print(w.wangbin)

总结:

如果在元table中去找相应的操作,例如__index,__newindex等,如果有则直接访问,如果没有就新添加进元table中

今天的关于lua __index __newindex upvalue 示例lua __index和__newindex的分享已经结束,谢谢您的关注,如果想了解更多关于Lua -- __index元方法、lua --- __newindex 的使用规则、lua setmetatable __index __newindex、lua 之__index/__newindex的理解的相关知识,请在本站进行查询。

本文标签: