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

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 表&#xff0c;包含一组元方法&#xff0c;这些元方法与 Lua 中的事件相关联。事件发生在 Lua 执行某些操作时&#xff0c;例如加法、字符串连接、比较等。元方法是普通的 Lua 函数&#xff0c;在特定事件发生时被调用。 元表包含了以下元方法&#xff1…...

基于Pyhton的人脸识别(Python 3.12+face_recognition库)

使用Python进行人脸编码和比较 简介 在这个教程中&#xff0c;我们将学习如何使用Python和face_recognition库来加载图像、提取人脸编码&#xff0c;并比较两个人脸是否相似。face_recognition库是一个强大的工具&#xff0c;它基于dlib的深度学习模型&#xff0c;可以轻松实…...

Spring Boot+Netty

因工作中需要给第三方屏幕厂家下发广告&#xff0c;音频&#xff0c;图片等内容&#xff0c;对方提供TCP接口于是我使用Netty长链接进行数据传输 1.添加依赖 <!-- netty依赖--><dependency><groupId>io.netty</groupId><artifactId>netty-all&…...

LCR 023. 相交链表

一.题目&#xff1a; LCR 023. 相交链表 - 力扣&#xff08;LeetCode&#xff09; 二.我的原始解法-无&#xff1a; 三.其他人的正确及好的解法&#xff0c;力扣解法参考&#xff1a; 哈希表法及双指针法&#xff1a;LCR 023. 相交链表 - 力扣&#xff08;LeetCode&#xff0…...

Linux命令行下载工具

1. curl 1.1. 介绍 curl是一个功能强大的命令行工具&#xff0c;用于在各种网络协议下传输数据。它支持多种协议&#xff0c;包括但不限于 HTTP、HTTPS、FTP、FTPS、SCP、SFTP、SMTP、POP3、IMAP 等&#xff0c;这使得它在网络数据交互场景中有广泛的应用。curl可以模拟浏览器…...

期末复习-Hadoop名词解释+简答题纯享版

目录 一、名称解释&#xff08;8选5&#xff09; 1.什么是大数据 2.大数据的5V特征 3.什么是SSH 4.HDFS&#xff08;p32&#xff09; 5.名称节点 6.数据节点 7.元数据 8.倒排索引 9.单点故障 10.高可用 11.数据仓库 二、简答题 1.简述Hadoop的优点及其含义 2.简述…...

嵌入式Linux无窗口系统下搭建 Qt 开发环境

嵌入式Linux无窗口系统下搭建 Qt 开发环境 本文将介绍如何在树莓派的嵌入式 Linux 环境下&#xff0c;搭建 Qt 开发环境&#xff0c;实现无窗口系统模式&#xff08;framebuffer&#xff09;下的图形程序开发。 1. 安装 Qt 环境 接下来&#xff0c;安装核心 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的优势&#xff1a; EasyExcel也是阿里研发在poi基础上做了封装&#xff0c;改进产物。它替开发者做了注解列表解析&#xff0c;表格填充等一系列代码编写工作&#xff0c;并将此抽象成通用和可扩展的框架。相对p…...

Spring Cloud + MyBatis Plus + GraphQL 完整示例

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

uni-app简洁的移动端登录注册界面

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

LongVU:用于长视频语言理解的空间时间自适应压缩

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

Elasticsearch数据迁移(快照)

1. 数据条件 一台原始es服务器&#xff08;192.168.xx.xx&#xff09;&#xff0c;数据迁移后的目标服务器&#xff08;10.2.xx.xx&#xff09;。 2台服务器所处环境&#xff1a; centos7操作系统&#xff0c; 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文件格式一样&#xff0c;PNG也是一种使用了算法压缩后的图像格式&#xff0c;与JPEG不同&#xff0c;PNG使用从LZ77派生的无损数据压缩算法。对于PNG文件格式&#xff0c;也有相应的开源工具libpng。 libpng库可从…...

【JavaWeb后端学习笔记】MySQL多表查询(内连接、外连接、子查询)

MySQL 多表查询 1、连接查询1.1 内连接1.2 外连接 2、子查询2.1 标量子查询2.2 列子查询2.3 行子查询2.4 表子查询 3、多表查询案例 多表查询有两大类&#xff1a;连接查询和子查询。 连接查询又分为隐式/显式内连接和左/右外连接。 子查询又分为标量子查询、列子查询、行子查询…...

RocketMQ 过滤消息 基于tag过滤和SQL过滤

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

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 提供了丰富的内置函数&#xff0c;涵盖了字符串处理、数值计算、日期时间操作、聚合分析以及控制流等多个方面。这些函数可以帮助用户更高效地进行数据查询和处理。 1.字符串函数 MySQL 提供了丰富的字符串函数来帮助用户处理和操作字符串数据。下面是一些常用的 MySQL…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...