lua 元表

这篇博客介绍了Lua中的元表概念及其应用,包括如何设置元表、使用__tostring和__call操作,以及运算符重载如__add、__sub等。此外,还探讨了__index和__newIndex在查找和赋值时的作用,展示了如何通过元表实现对象属性的动态查找和赋值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设置原表

元表
  • 任何表变量都可以作为另一个表变量的元表
  • 任何表变量都可以有自己的元表(父)
  • 当子表(有元表的这张表,子表是我自己的称呼,规范上没有)进行一些特定的操作时
  • 会执行元表的内容

--设置元表
 -- 先声明两张表
 meta = {}
 myTable = {}
-- 设置元表函数
-- 第一个参数 子表
-- 第二个参数 元表(爸爸)
setmetatable(myTable,meta)

特定操作 __tostring

-- 特定操作 __tostring
meta2={
	--当子表要被当成字符串使用时,会默认调用元表中的tostring方法
	__tostring = function()--注意,它这边有个坑,__tostring是两个下划线
	   return 'hello'
	end
}

myTable2 = {}

setmetatable(myTable2,meta2)
print(myTable2)

在这里插入图片描述
我们换种方式,假如我们想要获取的是下面myTable2中的666呢
在这里插入图片描述

因为是通过子表关联的元表,所以我们没有办法在元表内获取子表的666
我们改成下面的
在这里插入图片描述也就是说我在toString后加一个参数,当我们打印这个表的时候,会默认把自己传进去
传进去后就可通过参数.属性访问到这张表的属性了(当然这个是建立在我知道这张表的子表内的东西)

特定操作 __call

--特定操作 __call
Father = {
	--当子表(有元表的这张表)被当做一个函数来使用时,会默认调用这张表__call中的内容
	__call = function()
		print('execute')
	end
}

Son = {
	name = 'son'
}
setmetatable(Son,Father)
Son()

在这里插入图片描述

--检测__call是否能够带参
Father = {
	--想传参数时 切记 默认第一个参数 是调用者自己	
	__call = function(a,b)
		print(a)
		print(b)
	end
}

Son = {
	name = 'son'
}

setmetatable(Son,Father)
--将子表作为函数使用 调用元表 __call方法
Son(1)

在这里插入图片描述

特定参数 运算符重载

--运算符重载
father={
	--__add相当于运算符重载,当子表使用+运算符时 会调用该方法
	--加
	__add= function(a1,a2)
		return a1.num+a2.num
	end,
	--减
	__sub=function(a1,a2)
		return a1.num-a2.num
	end,
	--乘
	__mul=function(a1,a2)
		return a1.num*a2.num
	end,
	--除
	__div =function(a1,a2)
		return a1.num/a2.num
	end,
	--取余
	__mod = function(a1,a2)
		return a1.num%a2.num
	end,
	--幂运算
	__pow = function(a1,a2)
		return a1.num^a2.num		
	end,
	--运算符==
	__eq = function(a1,a2)
		return true
	end,
	--<
	__lt = function(a1,a2)
		return true
	end,
	--运算符<=
	__le = function(a1,a2)
		return false
	end,
	--运算符..
	__concat = function(a1,a2)
		return '666'
	end

}

son ={
	num=1
}
setmetatable(son,father);

son2 ={
	num=2
}
setmetatable(son2,father);


print(son+son2)
print(son-son2)
print(son*son2)
print(son/son2)
print(son%son2)--数A/数B,A小于B,商为0,余数就是它自己 1%2 余数1
print(son^son2)

--如果要用条件运算符 比较两个对象
--这两个对象的元表必须一致 才能准确调用方法
print(son==son2)
print(son<son2)
print(son<=son2)
print(son..son2)

特定操作 __index 和 __newIndex

__index

当子表中 找不到某个属性时
会到元表中 __index指定的表去找属性

--__index

  
meta6 = {
	age = 1,
	__index = { age=2 }
}

myTable6 = {}
setmetatable(myTable6,meta6)

print(myTable6.age)

在这里插入图片描述

meta6Father = {
	age = 2
}
meta6Father.__index = meta6Father

meta6 = {
	
}
--__index的赋值 最好写在表外面来初始化
meta6.__index = meta6

myTable6 = {}
setmetatable(meta6,meta6Father)
setmetatable(myTable6,meta6)

print(myTable6.age)

在这里插入图片描述

newindex

– 当赋值时,如果赋值一个不存在的索引
– 那么会把这个值到newindex所指的表中 不会修改自己

下面是正常的
在这里插入图片描述这个是加newindex
在这里插入图片描述

其他不常用方法

--其他较不常用方法
meta8 = {
	age = 1
}
myTable8 ={
	--age = 1
}
--得到元表的方法
print(getmetatable(myTable7))

--强制读取/写入第一个参数表的内存地址中的索引项
 --rawget 
 --从自己身上找有没有这个变量,不会去元表找
 print(rawget(myTable8,'age'))

 --rawset 
 --忽略newindex的设置 只会输出自己的变量
 rawset(myTable8,'age',6)
 print(myTable8.age)

在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值