lua 元表 __index __newindex rawset rawget

      今天在网上查询了一下自己困惑了很久的关于lua元表的问题,下面就将自己今天的
  收获写下来,如果有错的希望各位大神教导一下。
  	local m= {} 
  	m.mtable = {}
  
   	function m.new(t)
   			t = t or {}
   			setmetatable(t,m.mtable)            --- 设置元表    将m.mtable设置为t的元表
   			return t
  	end
	
	--	设置元表__index属性    可以是函数  也可以是表
	m.mtable.__index = {color = 'yellow',eyenum = 2}
	
	--设置元表__newindex 属性   可以是表 也可以是函数
	local other = {legnum = 2,eyenum = 2}
	m.mtable.__newindex = other
	
    --调用new方法  也就是将m.table设置为dog的元表  然后返回dog表
    local  dog = m.new({name='xiaohuang'})     
  
    print(dog.name)    --- 最基本的调用 调用dog表中属性为name的字段    返回xiaohuang

    print(dog.color)   ---这里在dog表中查找不到color属性,所以会去他的元表m.table中查找 如果找不到
  就会返回nil 找到就会返回属性对应的值        返回yellow 
  	
  	dog.eyenum = 30  -- dog 没有eyenum这个属性,会设置__newindex对应的表other中的eyenum
  	
  	print(dog.eyenum)     -- 一开始我还不知道rawset方法的时候 会想 在dog表里找不到eyenum属性 
  	就去元表中查找 然后设置值 不是应该会返回30吗   但是后来才知道 在给一个表里不存在的元素设置
  	值时,会去__newindex 中查找,找到则将对应索引的值设置进去或者将__newindex 对应的函数值返回      
  	那么这里__newindex 是一个表  找到eyenum元素 返回为2
  	
  	print(other.eyenum)   -- other.eyenum 的值已经被修改  会返回30



   上面写到__index,__newindex 可以是表  也可以是函数
	那下面也用函数写一下
	window = {}
	window.prototype={
			x = 10 ,
			y = 20 ,
			width = 100,
			height = 100
	}
    window.mt = {}
    function window.new(o)
    	o = o or {}
    	setmetatable(o,window.mt)
    end

   	window.mt.__index = window.prototype       --设置__index 属性  也就是上面申明的一个普通表

   	--这里设置__index属性是用函数方法  当__index是一个方法时,那么去查找元素的时候,如果表里没有该元素
   	--则返回方法返回值
	window.mt.__index = function (t,k)      
		return 1000
	end
	--设置__newindex  用函数方法
	window.mt.__newindex = function(t,k,v)
		if key ==  'myname' then rawset(table,'myname','yes i am') end 	
	end
	
	local w = window.new {
		x=10,
		y=20
	}
	
	print(w.name)   ---这里去w表中查找为name的元素  但是找不到  那么就去调用__index方法   这里返回1000
	
	w.myname = 'xxxx'  
	print(w.myname)     --这里调用__newindex方法  方法中设置以myname的值为yes i am   
	-- 所以这里返回yes i am

	那如果这里要设置的是w的其他属性 
	w.size ='1234'
	print(w.size)   --这里返回多少呢? 答案就是返回1000   和查找name的时候同理   而设置size在__newindex
	--方法中key不等于myname 所以没有设置进表里

  	那如果我想要返回1234应该怎么办呢? 可以在__newindex中将if判断去掉  改为rawset(t,k,v)
  	这样就可以将1234设置进w.size中了


	关于rawset  和 rawget 的理解  我感觉就像是c#中属性  set和get 差不多   set就是设置值的时候用
	而对于get   rawget我找到的是跳过某一个值  比如print(rawget(w,myname)) 这里就会返回nil  因为被跳过了
	但是我不是很懂这样跳过的具体用法,希望有大神解答!

    我的思路可能在大神眼里不是很严谨,我也就是把我研究这个知识的时候的想法写出来,希望能对和我一样水平的同学
    们有用吧~~~~(づ ̄ 3 ̄)づ
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值