lua 打印对table中的字段赋值时的堆栈

lua 打印对table中的字符赋值时的堆栈日志

今天日常码代码时遇到一个问题,对一个表的字段赋值时,后期使用时 不知何时,又在哪里改变了这个table中的字段的值,代码又很多,一行一行找很麻烦,我们可以使用 lua 中的元方法实现 当给table中的一个字段赋值时 我们就打印赋值堆栈日志 我们首先要了解 元方法 __index 和 __newindex

1. __index

lua中的元方法 __index 有 A ,B两个表, B是A的元表 , 当调用 A.a 的时候访问了A中不存在的字段 ,如果有元表,会调用 元表(B)中的__index 如果元表中没有 __index 方法,返回 nil 如例1

--例 1
	A = {
		
	}
	B = {
		a = 1
	}
	--设置元表
	setmetatable(A, B)

在这里插入图片描述

例2实现实现了预期的效果

--例 2
	A = {
		
	}
	B = {
		a = 1
	}
	B.__index = B
	--设置元表
	setmetatable(A, B)

在这里插入图片描述
__index 是一个表的时候 ,会去表中找到访问的字段。 当__index 是一个函数时会调用这个函数。

	A = {
		
	}
	B = {
		a = 1
	}
	B.__index = function(t, k)
		print("调用了__index元方法")
	end
	--设置元表
	setmetatable(A, B)

在这里插入图片描述
虽然调用了__index 但是还是返回了 nil, 在元方法中 return 需要的值即可

B.__index = function(t, k) 
	print("调用了__index元方法")
	return 1
end

在这里插入图片描述

2. __newindex

lua中的__newindex 元方法 跟 __index 元方法类型 __index 是访问一个不存在的字段时调用 __newindex 是对表中不存在的字段赋值时调用 __newindex 用于对表中不存在的字符赋值,赋值,赋值,__index 是访问, 访问, 访问
__newindex 是一个表时 对这个表赋值

	A = {
		
	}
	B = {
	
	}
	B.__newindex = B
	--设置元表
	setmetatable(A, B)
	A.name = "B"
	print(A.name)
	print(B.name)

在这里插入图片描述
这就是所谓的隔山打牛
当 __newindex 是一个方法时

	A = {
		
	}
	B = {
	
	}
	B.__newindex = function(t, k, v)
		print("调用了 __newindex 元方法")
	end
	--设置元表
	setmetatable(A, B)
	A.name = "B"
	print(A.name)
	print(B.name)

在这里插入图片描述
如果要设置值的话 不用 直接 t[k] = v (t 的元表中不能有 __newindex 元方法) 这样会进入死循环 ,使用 rawset(t, k, v) 忽略 __newindex引用

	A = {
		tag = "a"
	}
	B = {
		tag = "b"
	}
	B.__newindex = function(t, k, v)
		print("调用了 __newindex 元方法")
		print(t.tag)
		rawset(t,k,v)
	end
	--设置元表
	setmetatable(A, B)
	A.name = "B"
	print(A.name)
	print(B.name)

在这里插入图片描述

3.我们了解了 __index 和 __newindex 来实现我们的对表赋值时, 就打印日志是从何处赋值

	local assignment = function(monitor)
		-- monitor 需要监控的表
		if	monitor == nil or type(monitor) ~= "table" then 
			return
		end
		-- 赋值,访问 数据都存入cacheTable表,
		-- 这样的话 monitor表,一直是没有任何字段的,每次访问、赋值都会执行元方法 __index、__newindex
		local cacheTable = {}
		local _index = function(t, k)	
			return cacheTable[k]
		end
		local _newindex = function(t,k,v)
			print("字段名赋值 = " .. k, debug.traceback())
        	rawset(cacheTable, k, v)
		end
		setmetatable(monitor, {__index = _index, __newindex = _newindex})
	end
	A = {}
	assignment(A)
	A.name = "张三"
	A.sex = "男"
	A.age = "26"
	print(A.name)
	print(A.sex)
	print(A.age)

在这里插入图片描述
好了就记录到这里了希望对大家有帮助

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Aric@Zhang

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值