[lua]Lua中元表的简单应用

1、介绍

表的功能十分有限,使用元表可以改变表的行为从而增加表的功能,例如两个表相加。

2、设置元表

setmetatable方法用于设置表和元表的关联

getmetatable返回对象的元表

Ttab = {} --普通表
Metatab  = {} --元表
print(setmetatable(Ttab,Metatab))
print(Ttab)

从输出可见,通过setmetatable设置元表将返回和普通表相同的一个表

print(Metatab)
print(getmetatable(Ttab))

3、元表中的方法

(1)__index

当访问表的键时,没有对应键,则表将访问元表中的__index方法,该方法可以为一个表或者为函数。在元表中__index可以看作为一个键,其处理的是普通表没有设置键的值。

Ttab = {} --普通表
Metatab  = {} --元表
Metatab = {__index = function (Ttab,key)
	if key == "hong" then
		return "hello hong"
	else
		return "bye"
	end
end
}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
print(Ttab.ming)
print(Ttab.marry)
print(Ttab.hong)
print(Ttab.liu)

访问顺序:

普通表访问“ming”,找到对应值并返回为“hello ming”

普通表访问“marry”,普通表中没有对应键,所以访问元表中的__index方法,其方法对应的是一个函数,Ttab表示普通表,key为传入的键,当前键不满足条件则返回“bye”

普通表访问“hong”,当前普通表不存在该键,则访问元表中的__index方法,该键满足条件所以返回""hello hong"

普通表访问“liu”,当前普通表不存在该键,则访问元表中的__index方法,该键不满足条件所以返回"bye"

Ttab = {} --普通表
Metatab  = {} --元表
otherTab = {marry =  "hello marry",hong = "hello hong"} --用于__index访问的表
Metatab = {__index = otherTab}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
print(Ttab.ming)
print(Ttab.marry)
print(Ttab.hong)
print(Ttab.liu)

在__index指定的表中存在marry和hong索引,则当普通表访问到没有的索引时,则访问元表中__index对应的表

(2)__newindex

当为表添加的新的键值时,将会调用元表__newindex方法,该方法可以对应表或者函数。

Ttab = {} --普通表
Metatab  = {} --元表
otherTab = {} --用于__newindex访问的表
Metatab = {__newindex = otherTab}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表

Ttab.hong = "hello hong"

print(Ttab.ming)
print(Ttab.hong)
print(otherTab.hong)

由运行结果可以看出,当为普通表添加新的键值时,赋值时在普通表,但真正访问时却在otherTab表中,因为在元表中__newindex方法指定了otherTab表,所以在为普通表更新键值时,更新的键值将添加至__newindex指定表中

Ttab = {} --普通表
Metatab  = {} --元表
Metatab = {__newindex = function (tab,key,value)
	rawset(Ttab,key,value)
end}
Ttab = {ming = "hello ming"}
Ttab = setmetatable(Ttab,Metatab) --设置元表

Ttab.hong = "hello hong"

print(Ttab.ming)
print(Ttab.hong)

元表中的__newindex方法指定为一个函数,tab表示传入的表,key键,value值,使用rawset函数更新传入的表的内容

(3)添加运算符

当实现表+表时,直接使用将会出现报错,使用元表定义操作符可以有效处理

__add         对应操作符+

__sub          对应操作符-

__mul         对应操作符*

__div          对应操作符/

__mod         对应操作符%

__unm          对应操作符-

__concat         对应操作符...

__eq          对应操作符==

__lt         对应操作符<

__le          对应操作符<=

__gt         对应操作符>

以下以__add为例子,实现两张表对应位数值相加

Ttab = {} --普通表
Metatab  = {} --元表
Ytab = {} --普通表
Metatab = {__add = function(tab,newtab)
	if #tab == #newtab then
	for i =1 ,#tab do
		tab[i] = tab[i]+newtab[i]
	end
	end
end}
Ttab = {10,20,30}
Ytab = {20,30,40}
Ttab = setmetatable(Ttab,Metatab) --设置元表
temp = Ttab+Ytab
for k,v in pairs(Ttab) do
	print(k,v)
end

(4)__call

该方法意思为,当将表像函数调用时,将会调用__call对应的方法

Ttab = {} --普通表
Metatab  = {} --元表
Metatab = {__call = function(tab,arg)
	print(arg)
	return "Ttab"
end}
Ttab = setmetatable(Ttab,Metatab) --设置元表
str = Ttab(69)
print(str)

tab表示传入的表,arg表示传入参数

(5)__tostring

当表作为字符串使用时,将调用tostring对应的方法

Ttab = {} --普通表
Metatab  = {} --元表
Metatab = {__tostring = function (tab)
	local str = ""
	for k,v in pairs(tab) do
		str = str..v.." "
	end
	return str
end}
Ttab = {"ming,hong,wang,marry"}
Ttab = setmetatable(Ttab,Metatab) --设置元表
print(Ttab)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值