Lua 通过元方法简单实现属性Get/Set访问

通过元方法__index、__newindex、rawset,我们可以实现属性的Get/Set访问,类似于C#:

csharp 复制代码
public string name;
public string Name
{
    get => name;
    set => name = value;
}

方法一:将属性数据存在元表中

lua 复制代码
local meta = { name = "meta" }
meta.__index = function(self, key)
	print("Get Key = " .. tostring(key))
	return meta[key]
end
meta.__newindex = function(self, key, value)
	print("Set Key = " .. tostring(key) .. " , value = " .. tostring(value))
	meta[key] = value
end
local table = {}
setmetatable(table, meta)
print("------ 1 ------")
print(table.name)
print("------ 2 ------")
table.name = "table"
print("------ 3 ------")
print(table.name)

---输出结果:
-- ------ 1 ------
-- Get Key = name
-- meta
-- ------ 2 ------
-- Set Key = name , value = table
-- ------ 3 ------
-- Get Key = name
-- table

__index 可视为该table中所有属性的Get方法,通过参数Key区分不同的属性;
__newindex 可视为该table中所有属性的Set方法,通过参数Key区分不同的属性;

该方法的局限性在于,子表不得绕过元方法对属性进行修改(比如通过 rawset 方法),这是为了防止:因为子表有对应的属性,而无法触发到元表的 __index 方法

这也意味着,之后对于子表所有的属性获取与修改,都会反馈到元表上,子表永远都会是个空的table

方法二:将属性数据存在子表中

lua 复制代码
local meta = {
	__index = function(self, key)
		print("Get Key = " .. tostring(key))
		return self._TEMP_META_DATA_[key]
	end,
	__newindex = function(self, key, value)
		print("Set Key = " .. tostring(key) .. " , value = " .. tostring(value))
		rawset(self._TEMP_META_DATA_, key, value)
	end,
}
local table = {}
table._TEMP_META_DATA_ = {}
setmetatable(table, meta)
print("------ 1 ------")
print(table.name)
print("------ 2 ------")
table.name = 5
print("------ 3 ------")
print(table.name)

---输出结果:
-- ------ 1 ------
-- Get Key = name
-- 
-- ------ 2 ------
-- Set Key = name , value = 5
-- ------ 3 ------
-- Get Key = name
-- 5

该方法的优势在于,对子表的修改都能反馈到子表上,并由此可以衍生许多进阶写法

未完待续......

相关推荐
郝学胜-神的一滴12 分钟前
Effective Python 第44条:用纯属性与修饰器取代旧式的 setter 与 getter 方法
开发语言·python·程序人生·软件工程
程序员莫小特1 小时前
老题新解|计算2的N次方
开发语言·数据结构·算法·青少年编程·信息学奥赛一本通
white-persist3 小时前
XXE 注入漏洞全解析:从原理到实战
开发语言·前端·网络·安全·web安全·网络安全·信息可视化
人生导师yxc3 小时前
Java中Mock的写法
java·开发语言
半路程序员3 小时前
Go语言学习(四)
开发语言·学习·golang
沐知全栈开发4 小时前
C# 枚举(Enum)
开发语言
秦禹辰4 小时前
轻量级开源文件共享系统PicoShare本地部署并实现公网环境文件共享
开发语言·后端·golang
脑子慢且灵4 小时前
C语言与Java语言编译过程及文件类型
java·c语言·开发语言·汇编·编辑器
蒙奇D索大4 小时前
【C语言加油站】C语言文件操作详解:从“流”的概念到文件的打开与关闭
c语言·开发语言·笔记·学习·改行学it
武子康4 小时前
Java-144 深入浅出 MongoDB BSON详解:MongoDB核心存储格式与JSON的区别与应用场景
java·开发语言·数据库·mongodb·性能优化·json·bjson