Lua 元表及元方法

1: Lua 提供了元表(Metatable),允许我们改变table的行为,每个行为关联了对应的元方法。

例如,使用元表我们可以定义Lua如何计算两个table的相加操作a+b。

当Lua试图对两个表进行相加时,先检查两者之一是否有元表,之后检查是否有一个叫"__add"的字段,若找到,则调用对应的值。"__add"等即时字段,其对应的值(往往是一个函数或是table)就是"元方法"。

    语法:

  • setmetatable(table,metatable): 对指定 table 设置元表(metatable),如果元表(metatable)中存在 __metatable 键值,setmetatable 会失败。
  • getmetatable(table): 返回对象的元表(metatable)。
mytable = {"lua","C#","C++"}  --普通表
myMetatable = {}         --元表   元表扩展了普通表的行为
mytable = setmetatable(mytable,myMetatable) --用来设置元表
print(getmetatable(mytable))

2: 元方法的使用; 元方法是用来定义元表的行为

__index

1:第一种情况后接对应的方法:

mytable = {"lua","C#","C++"}  --普通表

--元表   元表扩展了普通表的行为
myMetatable = {
	__index = function(tab,key)
		print("调用了元表中的方法")
		-- body
	end
}       
mytable = setmetatable(mytable,myMetatable) --用来设置元表
--当访问普通表中的下标值时,可以访问的到,那么就返回对应值
print(mytable[1])
--当访问普通表中的下标值不存在时,这个时候就会去调用元方法,tab就是对应的普通表,key就是对应的下标值
print(mytable[10])

2:第二种情况接对应的表: 

mytable = {"lua","C#","C++"}  --普通表

myNewTable = {}
myNewTable[8] = "C"
myNewTable[9] = "PHP"
myNewTable[10] = "Python"
--元表   元表扩展了普通表的行为
myMetatable ={
__index = myNewTable
}        
mytable = setmetatable(mytable,myMetatable) --用来设置元表
--当访问普通表中的下标值时,可以访问的到,那么就返回对应值
print(mytable[1])
--当访问普通表中的下标值不存在时,这个时候就会去调用元方法,tab就是对应的普通表,key就是对应的下标值
print(mytable[10])   --Python

 __newindex

1:对应方法

--__newindex当我们对表的数据进行修改的时候,修改的是一个新的索引才会起作用
--当我们给表添加新的键值对的时候才会使用__newindex
mytable = {"lua","C#","C++"}  --普通表
myMetatable = {
	__newindex = function(tab,key,value)
		print("我们要修改的key为"..key.."把这个key值修改为:"..value)
		rawset(tab,key,value)
		-- body
	end
}
mytable = setmetatable(mytable,myMetatable)
mytable[1] = "C#"
mytable[5] = "Lua"
print(mytable[5])

 

3:为元表添加操作符

mytable = {"lua","java","C#","C++"}
myMetatable = {
	__add = function(tab,tab1)
		-- body
		print("调用加法操作符")
		local maxindex = 0
		maxindex = #tab
		for k,v in pairs(tab1) do
			maxindex = maxindex + 1
		     table.insert(tab,maxindex,v)
		end
	end
}
mytable = setmetatable(mytable,myMetatable)
newtable = {"PHP","Python"}
c = mytable+newtable --必须要有接收表
for k,v in pairs(mytable) do
	print(k,v)
end

      __add 键包含在元表中,并进行相加操作。 表中对应的操作列表如下:(注意:__是两个下划线)

模式描述
__add对应的运算符 '+'.
__sub对应的运算符 '-'.
__mul对应的运算符 '*'.
__div对应的运算符 '/'.
__mod对应的运算符 '%'.
__unm对应的运算符 '-'.
__concat对应的运算符 '..'.
__eq对应的运算符 '=='.
__lt对应的运算符 '<'.
__le对应的运算符 '<='.

4:__call方法调用。调用值时调用

--__call 元方法在 Lua 调用一个值时调用
mytable = {"lua","java","C#"}
myMetatable = {
	__call = function(tab,arg,arg2,arg3,arg4)
		-- body
		print("调用了Call方法",arg,arg2,arg3,arg4)
		return "xxz"
	end
}
mytable = setmetatable(mytable,myMetatable)
v = mytable(1,2,3)
print(v)

 5:__tostring方法调用。_tostring 元方法用于修改表的输出行为。

--__call 元方法在 Lua 调用一个值时调用
mytable = {"lua","java","C#"}
myMetatable = {
	__call = function(tab,arg,arg2,arg3,arg4)
		-- body
		print("调用了Call方法",arg,arg2,arg3,arg4)
		return "xxz"
	end,
	--__tostring  元方法在修改表的输出行为
	__tostring = function(tab)
		-- body
		a = ""
		for k,v in pairs(tab) do
			a = a ..v..","
		end
		return a
	end
}
mytable = setmetatable(mytable,myMetatable)
v = mytable(1,2,3)
print(v)
print(mytable)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EvanXZ

各位大佬 多多支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值