Lua元表和元方法的使用
元表是一个普通的 Lua 表,包含一组元方法,这些元方法与 Lua 中的事件相关联。事件发生在 Lua 执行某些操作时,例如加法、字符串连接、比较等。元方法是普通的 Lua 函数,在特定事件发生时被调用。
元表包含了以下元方法:
__add: 加法(+)运算。如果加法的任何操作数不是数字,Lua 将尝试调用元方法。它首先检查第一个操作数(即使它是一个数字);如果该操作数没有定义 __add 的元方法,则 Lua 将检查第二个操作数。如果 Lua 可以找到一个元方法,它将使用两个操作数作为参数调用该元方法,并且调用的结果(调整为一个值)是该操作的结果。否则,如果没有找到元方法,Lua 将引发错误。
__sub: 减法(-)运算。行为类似于加法运算。
__mul: 乘法(*)运算。行为类似于加法运算。
__div: 除法(/)运算。行为类似于加法运算。
__mod: 取模(%)运算。行为类似于加法运算。
__pow: 幂运算(^)。行为类似于加法运算。
__unm: 取反(一元 -)运算。行为类似于加法运算。
__idiv: 取整除(//)运算。行为类似于加法运算。
__band: 按位 AND(&)运算。行为类似于加法运算,但如果任何操作数既不是整数也不是可强制转换为整数的浮点数,Lua 将尝试使用元方法(参见 §3.4.3)。
__bor: 按位 OR(|)运算。行为类似于按位 AND 运算。
__bxor: 按位异或(二进制 ~)运算。行为类似于按位 AND 运算。
__bnot: 按位 NOT(一元 ~)运算。行为类似于按位 AND 运算。
__shl: 位运算左移 (<<) 操作。行为类似于位运算 AND 操作。
__shr: 位运算右移 (>>) 操作。行为类似于位运算 AND 操作。
__concat: 连接 (..) 操作。行为类似于加法操作,但如果任何操作数既不是字符串也不是数字(始终可以强制转换为字符串),Lua 将尝试使用元方法。
__len: 长度 (#) 操作。如果对象不是字符串,Lua 将尝试其元方法。如果存在元方法,Lua 会将对象作为参数调用它,并且调用的结果(始终调整为一个值)是操作的结果。如果不存在元方法但对象是表,则 Lua 会使用表长度操作(参见 §3.4.7)。否则,Lua 会引发错误。
__eq: 等于 (==) 操作。行为类似于加法操作,但只有当要比较的值都是表或都是完整用户数据且它们不是原始相等时,Lua 才尝试使用元方法。调用的结果始终转换为布尔值。
__lt: 小于 (<) 操作。行为类似于加法操作,但只有当要比较的值既不是数字也不是字符串时,Lua 才尝试使用元方法。此外,调用的结果始终转换为布尔值。
__le: 小于等于 (<=) 操作。行为类似于小于操作。
__index: 索引访问操作 table[key]。当 table 不是表或当 key 不存在于 table 中时,会发生此事件。元值在 table 的元表中查找。
注:
Lua 查找一个表元素时的规则如下 :
1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
3.判断元表有没有 __index 方法,如果 __index 方法为 nil,则返回 nil;如果 __index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。
__newindex: 索引赋值 table[key] = value。与索引事件类似,当 table 不是表或当 key 不存在于 table 中时,会发生此事件。元值在 table 的元表中查找。
__call:调用操作 func(args)。当 Lua 尝试调用非函数值(即 func 不是函数)时,会发生此事件。元方法在 func 中查找。如果存在,则使用 func 作为第一个参数调用元方法,后跟原始调用的参数 (args)。调用的所有结果都是操作的结果。这是允许多个结果的唯一元方法。
下面使用lua元表和元方法模拟Vector3运算的例子:
local meta = {}
local vector3 = {}function vector3.new (x,y,z)local v = {x = x, y = y, z = z}setmetatable(v,meta);return v
endfunction vector3.add(v1,v2)return vector3.new(v1.x + v2.x,v1.y + v2.y,v1.z + v2.z)
endfunction vector3.substrct(v1,v2)return vector3.new(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z)
endfunction vector3.multiply(v1, v2)return vector3.new(v1.x * v2.x,v1.y * v2.y,v1.z * v2.z)
endfunction vector3.Divide(v1,v2)return vector3.new(v1.x / v2.x,v1.y / v2.y,v1.z / v2.z)
endfunction vector3.equals(v1,v2)return v1.x - v2.x == 0 and v1.y - v2.y == 0 and v1.z - v2.z == 0
endfunction vector3.tostring(v)return "("..v.x.." , "..v.y.." , "..v.z..")"
endfunction printNil()return "__index :没有找到key值"
endfunction printNil2(mytable, key,value)return print("__newindex :没有key值")
endfunction printNil3(mytable, ...)for i,j in pairs({...}) doprint(i,j)endreturn "调用 call 方法";
endmeta.__add = vector3.add
meta.__sub = vector3.substrct
meta.__mul = vector3.multiply
meta.__div = vector3.Divide
meta.__eq = vector3.equals
meta.__tostring = vector3.tostring
--索引访问操作 table[key]。
--当 table 不是表或当 key 不存在于 table 中时,会发生此事件。
--元值在 table 的元表中查找
meta.__index = printNil
--索引赋值 table[key] = value。
--当 table 不是表或当 key 不存在于 table 中时,会发生此事件。
--元值在 table 的元表中查找
meta.__newindex = printNil2
--[[
调用操作 func(args)。当 Lua 尝试调用非函数值(即 func 不是函数)时,会发生此事件。
元方法在 func 中查找。如果存在,则使用 func 作为第一个参数调用元方法,
后跟原始调用的参数 (args)。调用的所有结果都是操作的结果。这是允许多个结果的唯一元方法。
]]
meta.__call = printNil3local pos1 = vector3.new(5,6,7)
local pos2 = vector3.new(8,9,10)print(pos1 + pos2)
print(pos1 - pos2)
print(pos1 * pos2)
print(pos1 / pos2)
print(pos1 == pos2)
print(pos1.w)
pos1.rotation = pos2
print(pos1(2,3,4,5,6))
结果:
参考书籍与链接:
《Lua程序设计》
Metamethods - Lua Tutorial (Part 16) (youtube.com)
Master the Lua Scripting Language (pikuma.com)
lua-users wiki:Lua 目录 - Lua 编程语言
相关文章:

Lua元表和元方法的使用
元表是一个普通的 Lua 表,包含一组元方法,这些元方法与 Lua 中的事件相关联。事件发生在 Lua 执行某些操作时,例如加法、字符串连接、比较等。元方法是普通的 Lua 函数,在特定事件发生时被调用。 元表包含了以下元方法࿱…...

基于Pyhton的人脸识别(Python 3.12+face_recognition库)
使用Python进行人脸编码和比较 简介 在这个教程中,我们将学习如何使用Python和face_recognition库来加载图像、提取人脸编码,并比较两个人脸是否相似。face_recognition库是一个强大的工具,它基于dlib的深度学习模型,可以轻松实…...
Spring Boot+Netty
因工作中需要给第三方屏幕厂家下发广告,音频,图片等内容,对方提供TCP接口于是我使用Netty长链接进行数据传输 1.添加依赖 <!-- netty依赖--><dependency><groupId>io.netty</groupId><artifactId>netty-all&…...

LCR 023. 相交链表
一.题目: LCR 023. 相交链表 - 力扣(LeetCode) 二.我的原始解法-无: 三.其他人的正确及好的解法,力扣解法参考: 哈希表法及双指针法:LCR 023. 相交链表 - 力扣(LeetCode࿰…...
Linux命令行下载工具
1. curl 1.1. 介绍 curl是一个功能强大的命令行工具,用于在各种网络协议下传输数据。它支持多种协议,包括但不限于 HTTP、HTTPS、FTP、FTPS、SCP、SFTP、SMTP、POP3、IMAP 等,这使得它在网络数据交互场景中有广泛的应用。curl可以模拟浏览器…...
期末复习-Hadoop名词解释+简答题纯享版
目录 一、名称解释(8选5) 1.什么是大数据 2.大数据的5V特征 3.什么是SSH 4.HDFS(p32) 5.名称节点 6.数据节点 7.元数据 8.倒排索引 9.单点故障 10.高可用 11.数据仓库 二、简答题 1.简述Hadoop的优点及其含义 2.简述…...
嵌入式Linux无窗口系统下搭建 Qt 开发环境
嵌入式Linux无窗口系统下搭建 Qt 开发环境 本文将介绍如何在树莓派的嵌入式 Linux 环境下,搭建 Qt 开发环境,实现无窗口系统模式(framebuffer)下的图形程序开发。 1. 安装 Qt 环境 接下来,安装核心 Qt 开发库以及与 …...
C#基础教程
1. C# 基础语法和操作符 C# 中的运算符优先级 namespace OperatorsAppl {class Program7{static void Main(string[] args){int a 20; // 定义变量aint b 10; // 定义变量bint c 15; // 定义变量cint d 5; // 定义变量dint e; // 定义变量e// 演示运算符优先级&…...

Alibaba EasyExcel 导入导出全家桶
一、阿里巴巴EasyExcel的优势 首先说下EasyExcel相对 Apache poi的优势: EasyExcel也是阿里研发在poi基础上做了封装,改进产物。它替开发者做了注解列表解析,表格填充等一系列代码编写工作,并将此抽象成通用和可扩展的框架。相对p…...

Spring Cloud + MyBatis Plus + GraphQL 完整示例
Spring Cloud MyBatis Plus GraphQL 完整示例 1、创建Spring Boot子项目1.1 配置POM,添加必要的依赖1.2 配置MyBatis-Plus 2、集成GraphQL2.1 定义schema.graphqls2.2 添加GraphQL解析器2.3 配置schame文件配置 3、访问测试3.1 查询测试(演示ÿ…...

uni-app简洁的移动端登录注册界面
非常简洁的登录、注册界面模板,使用uni-app编写,直接复制粘贴即可,无任何引用,全部公开。 废话不多说,代码如下: login.vue文件 <template><view class"content"><view class&quo…...

LongVU:用于长视频语言理解的空间时间自适应压缩
晚上闲暇时间看到一种用于长视频语言理解的空间时间自适应压缩机制的研究工作LongVU,主要内容包括: 背景与挑战:多模态大语言模型(MLLMs)在视频理解和分析方面取得了进展,但处理长视频仍受限于LLM的上下文长…...

Elasticsearch数据迁移(快照)
1. 数据条件 一台原始es服务器(192.168.xx.xx),数据迁移后的目标服务器(10.2.xx.xx)。 2台服务器所处环境: centos7操作系统, elasticsearch-7.3.0。 2. 为原始es服务器数据创建快照 修改elas…...

Linux Cgroup学习笔记
文章目录 Cgroup(Control Group)引言简介Cgroup v1通用接口文件blkio子系统cpu子系统cpuacct子系统cpuset子系统devices子系统freezer子系统hugetlb子系统memory子系统net_cls子系统net_prio子系统perf_event子系统pids子系统misc子系统 Cgroup V2基础操作组织进程和线程popula…...
百问FB显示开发图像处理 - PNG图像处理
2.3 PNG图像处理 2.3.1 PNG文件格式和libpng编译 跟JPEG文件格式一样,PNG也是一种使用了算法压缩后的图像格式,与JPEG不同,PNG使用从LZ77派生的无损数据压缩算法。对于PNG文件格式,也有相应的开源工具libpng。 libpng库可从…...
【JavaWeb后端学习笔记】MySQL多表查询(内连接、外连接、子查询)
MySQL 多表查询 1、连接查询1.1 内连接1.2 外连接 2、子查询2.1 标量子查询2.2 列子查询2.3 行子查询2.4 表子查询 3、多表查询案例 多表查询有两大类:连接查询和子查询。 连接查询又分为隐式/显式内连接和左/右外连接。 子查询又分为标量子查询、列子查询、行子查询…...

RocketMQ 过滤消息 基于tag过滤和SQL过滤
RocketMQ 过滤消息分为两种,一种tag过滤,另外一种是复杂的sql过滤。 tag过滤 首先创建producer然后启动,在这里创建了字符串的数组tags。字符串数组里面放置了多个字符串,然后去发送15条消息。 15条消息随着i的增长,…...

element-ui 基本样式的一些更改【持续更新】
1、 去除el-tabs的底部灰色横线 ::v-deep .el-tabs__nav-wrap::after {height: 0px;}2、el-table设置表头颜色 <el-table:data"tableData":header-cell-style"{background:#F7F8FA,color:#4E5869}"><el-table-columnlabel"序号"type&qu…...
element-ui radio和checkbox禁用时不置灰还是原来不禁用时的样式
把要紧用的内容加上一个class"notEdit-page" z注意要在style里面写不能加上scoped /*//checkBox自定义禁用样式*//*//checkBox自定义禁用样式*/ .notEdit-page.el-checkbox__input.is-disabled.is-checked.el-checkbox__inner::after {border-color: #fff; } .notEdi…...
第一部分:基础知识 6. 函数 --[MySQL轻松入门教程]
MySQL 提供了丰富的内置函数,涵盖了字符串处理、数值计算、日期时间操作、聚合分析以及控制流等多个方面。这些函数可以帮助用户更高效地进行数据查询和处理。 1.字符串函数 MySQL 提供了丰富的字符串函数来帮助用户处理和操作字符串数据。下面是一些常用的 MySQL…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...