当前位置: 首页 > news >正文

Lua元表(Metatable)

元表的基本概念

元表(Metatable)是Lua中一种特殊的表,用于定义或扩展其他表的行为。通过元表,可以自定义表的操作方式,例如加法、减法、索引、调用等。每个表可以关联一个元表,元表本身也是一个普通的表,但包含特定的元方法(Metamethods)来定义行为。

设置和获取元表

使用setmetatable(table, metatable)为表设置元表,getmetatable(table)获取表的元表。元表通常包含一系列以双下划线(__)开头的键,称为元方法。

local t = {}
local mt = {}
setmetatable(t, mt) -- 设置mt为t的元表
print(getmetatable(t) == mt) -- 输出true

常用元方法

算术运算元方法
  • __add: 定义加法操作(+
  • __sub: 定义减法操作(-
  • __mul: 定义乘法操作(*
  • __div: 定义除法操作(/
  • __mod: 定义取模操作(%
  • __pow: 定义幂运算操作(^
  • __unm: 定义负号操作(-

示例:

local vec1 = {x = 1, y = 2}
local vec2 = {x = 3, y = 4}
local mt = {__add = function(a, b)return {x = a.x + b.x, y = a.y + b.y}end
}
setmetatable(vec1, mt)
setmetatable(vec2, mt)
local vec3 = vec1 + vec2
print(vec3.x, vec3.y) -- 输出4, 6

关系运算元方法
  • __eq: 定义相等操作(==
  • __lt: 定义小于操作(<
  • __le: 定义小于等于操作(<=

示例:

local mt = {__eq = function(a, b)return a.value == b.valueend
}
local a = {value = 10}
local b = {value = 10}
setmetatable(a, mt)
setmetatable(b, mt)
print(a == b) -- 输出true

其他元方法
  • __index: 定义当访问表中不存在的键时的行为。
  • __newindex: 定义当给表中不存在的键赋值时的行为。
  • __call: 定义当表被调用时的行为。
  • __tostring: 定义当表被转换为字符串时的行为。
  • __len: 定义当使用#操作符获取表长度时的行为。

__index 元方法

__index可以是一个函数或表。如果是表,当键不存在时会从该表中查找;如果是函数,则会调用函数并返回结果。

示例(函数形式):

local mt = {__index = function(table, key)return "Key " .. key .. " not found"end
}
local t = {}
setmetatable(t, mt)
print(t.name) -- 输出"Key name not found"

示例(表形式):

local defaults = {name = "Unknown", age = 0}
local mt = {__index = defaults}
local t = {}
setmetatable(t, mt)
print(t.name) -- 输出"Unknown"

__newindex 元方法

__newindex可以是一个函数或表。如果是表,赋值操作会修改该表;如果是函数,则会调用函数处理赋值。

示例(函数形式):

local mt = {__newindex = function(table, key, value)rawset(table, key, value .. " (modified)")end
}
local t = {}
setmetatable(t, mt)
t.name = "Alice"
print(t.name) -- 输出"Alice (modified)"

__call 元方法

允许表像函数一样被调用。

示例:

local mt = {__call = function(table, arg)print("Called with", arg)end
}
local t = {}
setmetatable(t, mt)
t(42) -- 输出"Called with 42"

__tostring 元方法

自定义表的字符串表示形式。

示例:

local mt = {__tostring = function(table)return "Table: " .. table.nameend
}
local t = {name = "Test"}
setmetatable(t, mt)
print(t) -- 输出"Table: Test"

使用rawgetrawset

rawget(table, key)rawset(table, key, value)可以绕过元方法直接操作表,避免递归调用。

示例:

local t = {}
local mt = {__newindex = function(table, key, value)rawset(table, key, value * 2) -- 直接赋值,避免递归end
}
setmetatable(t, mt)
t.x = 10
print(t.x) -- 输出20

元表的继承

通过__index可以实现类似继承的效果。

示例:

local parent = {name = "Parent"}
local child = {}
setmetatable(child, {__index = parent})
print(child.name) -- 输出"Parent"

Warring:

  • 元表的功能强大,但滥用可能导致代码难以维护。
  • 避免在元方法中执行耗时操作,可能影响性能。
  • 元表是Lua实现面向对象编程的基础机制之一。
http://www.dtcms.com/a/296068.html

相关文章:

  • 【Python机器学习】4.2. 数据分离与混淆矩阵
  • 在原生Android项目中集成React Native实践
  • 《面向互联网2C业务的分布式类Manus Java框架》系统解析
  • YOLO11有效涨点优化:注意力魔改 | 新颖的多尺度卷积注意力(MSCA),即插即用,助力小目标检测
  • Java与NLP实战:文本处理到情感分析全解析
  • 基于Node.js开发的开源博客平台ghost安装和使用
  • 【科研绘图系列】R语言绘制双侧坐标轴的条形图
  • Java并发编程第六篇(AQS设计理念与源码解析)
  • TechGPT3部署
  • kafka的shell操作
  • 【Atlassian生态】Jira Cloud单站点现可支持10万用户:架构升级与龙智云迁移服务
  • 【C++造轮子】手撕list容器:从零实现STL链表架构
  • FFT算法实现之fft IP核
  • 无人机抛投模块分析
  • 基于 AI 的 Markdown 笔记应用HelloGitHub 评分
  • Springmvc的自动解管理
  • 开源项目XBuilder前端框架
  • 零知识证明
  • 物流仓储自动化升级:Modbus TCP与DeviceNet的协议融合实践
  • Git 下载
  • 三维手眼标定
  • 车规级CANFD芯片在汽车车身控制方案中的应用解析
  • 雨季,汽车经常跑山区,该如何保养?
  • 汽车需求管理的关键要素及适合汽车行业的最佳需求管理解决方案Jama Connect
  • 【世纪龙科技】大众车身电气技术仿真教学软件-赋能汽车电气教学
  • 格雷希尔快速封堵头,针对新能源汽车冷却系统进出水口快速封堵的解决方案特点及应用分析
  • 高亮标题里的某个关键字正则表达式
  • c#正则表达式
  • Q2桥门式起重机司机主要应用在哪些行业
  • Etcd原理基础学习