Lua学习 -- 元表(Metatable)

设置元表

(似乎只能用 // 来注释?)

local mymetatable = {} //元表
local mytable = {} //表
//将mymetatable设置为mytable的元表
mytable = setmetatable(mytable,mymetatable) 

元表是用来存放一些元方法,当对表执行某些指定操作时就会执行相应的元方法。

注意元方法的"__“是两个”_"

__index元方法

查询表时

local mytable1 = setmetatable({key1 = 1},{__index = {key2 = 2}})
print(mytable1.key1,mytable1.key2)
//这两种写法的结果相同-----------------------------------
local mytable2 = setmetatable({key1 = 11},{__index = function(mytable,key)
		if key == "key2" then 
			return 22
		else
			return nil
		end
	end
})
print(mytable2.key1,mytable2.key2)

解析:

1.为mytable设置元表,
2.查询mytable中key1和key2键对应的值,
3.在mytable表中查询到key1键,返回对应的值,
4.在mytable中未找到key2键,查看mytable是否有元表,
5.有元表,在元表中是否有__index元方法,
6.(1)有__index元方法,元方法为表,则重复查询操作,
  (2)有__index元方法,元方法为函数,将查询的表和key值作为形参传入函数,返回函数返回值,
7.输出结果

运行结果:

1       2
11      22

__newindex元方法

表更新时

local newtable = {key2 = 2,key3 = 3}
local mytable3 = setmetatable({key1 = 1},{__newindex = newtable})
mytable3.key1 = 11
mytable3.key2 = 22
mytable3.key4 = 44
print(mytable3.key1,mytable3.key2,mytable3.key3,mytable3.key4)
print(newtable.key1,newtable.key2,newtable.key3,newtable.key4)

解析:

-- mytable3.key1 = 11--
1.查询mytable3中是否有key1键,
2.有key1键,将mytable3表中的key1键的值改为11

-- mytable3.key2 = 22--
1.查询mytable3中是否有key2键,
2.没有key2键,查询是否有元表,
3.有元表,查询是否有__newindex元方法,
4.有__newindex元方法,且元方法为表,查询元方法的表中是否有key2键,
5.有key2键,将key2键的值修改为22

-- mytable3.key4 = 44--
1.查询mytable3中是否有key4键,
2.没有key4键,查询是否有元表,
3.有元表,查询是否有__newindex元方法,
4.有__newindex元方法,且元方法为表,查询元方法的表中是否有key4键,
5.没有key4键,对元表重复之前的赋值操作(没有元表就直接对表进行更新),
6.将key4 = 44元素添加到表newtable中

运行结果:

11      nil     nil     nil
nil     22      3       44
local mytable4 = setmetatable({key1 = 1},{__newindex = function(mytable4,key,value)
		rawset(mytable4,key,value)
	end
})
mytable4.key2 = 2
print(mytable4.key1,mytable4.key2)

解析:

1.查找mytable4中是否有key2键,
2.没有key2键,查看是否有元表,
3.有元表,元表中是否有__newindex元方法,
4.有__newindex元方法,且元方法为函数,将table,key,value作为参数,
5.执行函数
****************延伸***************
rawset:无视元表,直接对表进行更新操作
rawget:无视元表,直接对表进行查询操作

运行结果:

1       2

操作符

两表运算时
(以加为例)

local mytable5 = setmetatable({1,2,3},{__add = function (table1,table2)
	for k,v in pairs(table1) do
		table1[k] = table1[k] + table2[k]
	end
	return table1
end})
local mytable6 = {4,5,6}
local sumtable = mytable5 + mytable6
for k,v in pairs(sumtable) do
	print(v)
end

解析:

1.mytable5元素为{1,2,3}且设置的元表,
2.执行“+”操作,查看元表中是否有__add键,
3.有,执行__add的函数,传入两个表为参数,返回函数返回值

运行结果:

5
7
9

元表键与运算符对应关系

运算符
__add+ (加法)
__sub- (减法)
__mul* (乘法)
__div/ (除法)
__mod% (模除)
__unm-(一元减操作符)
__concat…(连接符)
__eq== (等于)
__lt< (小于)
__le<= (小于等于)

__call元方法

调用表时

local mytable7 = setmetatable({1,2,3},{__call = function (mytable,num)
	for k,v in pairs(mytable) do
		print(k,v,num)
	end
end})
mytable7(12) //执行元表中的__call元方法,传入表和参数作为元方法参数

运行结果:

1       1       12
2       2       12
3       3       12

__tostring元方法

输出表时

local mytable8 = setmetatable({11,22,33,44,55,66,77,88},{__tostring = function (mytable)
	local sum = 0
	for k,v in pairs(mytable) do
		print("key:"..k.."=====value:"..v)
		sum = sum + v
	end
	return "sum===="..sum
end})
print(mytable8) //执行元表中的__tostring元方法

运行结果:

key:1=====value:11
key:2=====value:22
key:3=====value:33
key:4=====value:44
key:5=====value:55
key:6=====value:66
key:7=====value:77
key:8=====value:88
sum====396

总结

  • __index:对表通过键查询时调用,若为表则继续查询__index表,若为函数则执行函数(table,key)
  • __newindex:对表添加新键值时调用,若为表则继续添加键值给__newindex表,若为函数则执行函数(table,key,value)
  • 操作符:对两个表进行运算时,执行元表(默认为被运算表的元表,若没有则为运算表的元表)中对应键的方法(table1,table2)
  • __call:当将表当做函数调用时,执行该元方法(table)
  • __tostring:当对表进行输出操作时实行(注:输出只能写为 print(table) 形式,不能添加其他输出
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值