Lua语法详解之元表(概念,设置,获取,运算符重载,__string,__call,__index,__newindex,rawget,rawset)

(一)元表的概念
–任何表变量都可以作为另一个表变量的元表
–任何表变量都可以有自己的元表
–有元表的那张表相当于子表
–作用:当对子表进行一些特定操作时,会执行元表中的内容

(二)设置元表

--如何设置元表
metatable={}
mytable={}
--第一参数子表,第二个参数元表
setmetatable(mytable,mytable)

(三)元表的特定操作
(1)元表的特定操作_tostring,把子表当成某个设定好的特定字符串

--元表的特定操作__tostring,把子表当成某个设定好的特定字符串,可以用作获取子表的名字
--注意这里是两根下划线
metatable3={
	__tostring=function()
		return "mytable3"
	end

}
mytable3={
	
}
print(mytable3)--table: 0x7fbafe904b10,没设置元表浅,打印表的内存单元
setmetatable(mytable3,metatable3)
print(mytable3)--mytable3,设置了元表后,打印元表的__tostring返回的字符串
--修改元表,让其能打印子表中的属性
metatable4={
	__tostring=function(t)
		return t.name
	end

}
mytable4={
	name="hello"
}
setmetatable(mytable4,metatable4)
print(mytable4)--hello,注意这里调用__tostring,并没有传参数
			   --所以这样写是默认调用__string(metable4)

(2)元表的特定操作_call,把子表当成一个特定的函数使用时,用元表里的__call函数
且默认的第一个参数是子表本身

--元表的特定操作__call
--当子表被当作一个函数来使用时,会默认调用__call中的内容,默认的第一个参数是子表本身
metatable5={
	__tostring=function(t)
		return t.name
	end,
	__call=function(a)--这里有个默认参数是子表
		print(a.sex)
		print("__call fun")
	end

}
mytable5={
	name="hello",
	sex="false"
}
setmetatable(mytable5,metatable5)
print(mytable5)
--把表作为函数用时
mytable5()--false __call fun,调用了元表里的__call方法,并把子表本身作为了默认的第一个参数

(3)元表的特定操作运算符重载
–元表的特定操作运算符重载
–也就是说通过元表可以定义表之间的运算,__add,__sub,__mul,__div,_mod(取余),_pow(幂),_eq(),_lt(<),_le(<=),_concat(拼接)
–如果要用条件运算符(如:_eq(
),_lt(<),_le(<=))来比较两个表对象,那么这两个表对象的元表要一致,才能比较

--元表的特定操作运算符重载
--也就是说通过元表可以定义表之间的运算,__add,__sub,__mul,__div,_mod(取余),_pow(幂)
--_eq(==),_lt(<),_le(<=),_concat(拼接)
metatable7={
	__add=function(t1,t3)
		return t1.age+t3.age
	end
}
mytable7={age=4}
mytable8={age=5}

setmetatable(mytable7,metatable7)
print(mytable7+mytable8)--9,用的是元表里__add的运算

(4)元表的特定操作_index
–当子表中找不到某个变量时,回到元表的__index指定的表中去寻找该变量
–而且__index最好写在表外面,写里面有的时候不正确
–而且__index还可以一层层往上找

--元表的特定操作__index
--当子表中找不到某个变量时,回到元表的__index指定的表中去寻找该变量
metatable8={}
mytable8={}
testtable={age=13}
setmetatable(mytable8,metatable8)
metatable8.__index=testtable--将元表的__index指向的表指向了testtable
metatable8.__index={age=14}--这种写法也可以
print(mytable8.age)--13

(5)元表的特定操作_newIndex

--元表的特定操作__newIndex
--当赋值时,如果赋值一个不存在的索引,那么会把这个值赋值到newindex所指的表中,不会修改自己
--相当于把值设置给了元表,而不是子表自己?
mytable10={}
metatable10={}
metatable10.__newindex={}
setmetatable(mytable10,metatable10)
mytable10.age=13--相当于给mytable表里添加了一个age属性
print(mytable10.age)--但是这里打印的事nil
print(metatable10.__newindex.age)--13

(6)获取元表

print(getmetatable(mytable10))--table: 0x7f96fa908a90

(7)只在自己的表中找,不去元表找,绕开__index

mytable={age=1}
print(rawget(mytable,"age"))

(8)只给自己的表中的元素设置值,不会设置元表,绕开__newIndex

mytable={age=1}
print(rawget(mytable,"age"))--1

rawset(mytable,"age",3)
print(mytable.age)--3
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值