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 函数,在特定事件发生时被调用。 元表包含了以下元方法࿱…...
自动驾驶算法——卡尔曼滤波器平滑感知车道线参数【C++代码实现】
1.算法原理 在工程实践中,由于感知识别到的车道线偶尔存在较大的跳变,导致后端控制算法计算出的控制角度也存在较大的跳变,所以我们需要对感知输入的车道线系数进行平滑处理。 已知卡尔曼滤波算法主要分为以下几大步骤: 感知将车道线以三次螺旋曲线方程 y = c 0 + c 1 x +…...
浅谈Scala语言
一、Scala语言基础 1.1 语法结构 Scala的语法是一种融合了多种编程范式的设计,它结合了函数式编程和面向对象编程的优点。这种语法结构使得Scala既具有高度的表达能力,又保持了代码的简洁性。例如,Scala支持类型推断,这意味着在…...
可视化建模以及UML期末复习篇----UML图
这是一篇相对较长的文章,如你们所见,比较详细,全长两万字。我不建议你们一次性看完,直接跳目录找你需要的知识点即可。 --------欢迎各位来到我UML国! 一、UML图 总共有如下几种: 用例图(Use Ca…...
音视频入门基础:MPEG2-TS专题(13)——FFmpeg源码中,解析Section Header的实现
一、引言 在《音视频入门基础:MPEG2-TS专题(11)—— TS中的Section》中讲述了Section Header的基本概念,本文讲述FFmpeg源码中是怎样解析Section Header的。 二、parse_section_header函数的定义 FFmpeg源码中通过parse_section…...
SQL UCASE() 函数:转换字符串为大写
SQL UCASE() 函数:转换字符串为大写 概述 在SQL中,UCASE() 函数用于将字符串中的所有字符转换为大写。这是一个非常实用的函数,尤其在处理大量文本数据时,确保数据的一致性和准确性。本文将详细介绍UCASE() 函数的用法、示例以及…...
机器学习周报(12.2-12.8)
文章目录 摘要Abstract Vision Transformer1 原理2 代码 摘要 本周学习了Vision Transformer (ViT) 的基本原理及其实现,并完成了基于PyTorch的模型训练、验证和预测任务。深入理解了ViT如何将图像分割成patch作为输入序列,并结合Transformer Encoder处…...
【机器人】系统辨识之激励轨迹设计(傅里叶级数)
在机器人参数辨识中使用傅里叶级数,主要是为了生成一种激励轨迹,具有良好的数学特性,同时符合物理要求。傅里叶级数的特性使其在机器人动力学辨识的激励轨迹设计中非常常用。 1. 为什么需要激励轨迹? 激励轨迹的作用是通过驱动机…...
JVM八股文精简
目录 简述JVM类加载过程简述JVM中的类加载器简述双亲委派机制双亲委派机制的优点简述JVM内存模型简述程序计数器简述虚拟机栈简述本地方法栈简述JVM中的堆简述方法区简述运行时常量池简述Java创建对象的过程简述JVM给对象分配内存的策略Java对象内存分配是如何保证线程安全的如…...
PyTorch基本使用——张量的索引操作
在操作张量时,经常要去获取某些元素进行处理或者修改操作,在这里需要了解torch中的索引操作。 准备数据: data torch.randint(0,10,[4,5]) print(data--->,data)输出结果: data---> tensor([[3, 9, 4, 0, 5],[7, 5, 9, …...
mysql集群MHA方式部署
1. 基本信息 部署机器角色部署路径192.168.242.71MySQL-Mater MHA-NodeMySQL: /alidata1/mysql-8.0.28192.168.242.72MySQL-Slave MHA-NodeMHA-Node: /alidata1/admin/tools/mha4mysql-node-0.58192.168.242.73MySQL-Slave MHA-Node192.168.242.74MHA-ManagerMHA-Manager: …...
Spring Boot中实现JPA多数据源配置指南
本文还有配套的精品资源,点击获取 简介:本文详细介绍了在Spring Boot项目中配置和使用JPA进行多数据源管理的步骤。从引入依赖开始,到配置数据源、创建DataSource bean、定义实体和Repository,最后到配置事务管理器和使用多数据…...
【计算机网络】实验12:网际控制报文协议ICMP的应用
实验12 网际控制报文协议ICMP的应用 一、实验目的 验证ping命令和tracert命令的工作原理。 二、实验环境 Cisco Packet Tracer模拟器 三、实验过程 1.构建网络拓扑并进行信息标注,将所需要配置的IP地址写在对应的主机或者路由器旁边,如图1所示。 图…...
MVC基础——市场管理系统(二)
文章目录 项目地址三、Produtcts的CRUD3.1 Products列表的展示页面(Read)3.1.1 给Product的Model里添加Category的属性3.1.2 View视图里展示Product List3.2 增加Product数据(Add)3.2.1 创建ViewModel用来组合多个Model3.2.2 在_ViewImposts里引入ViewModels3.2.3 添加Add的…...
使用Redis的Bitmap实现签到功能
1.基础签到实现 1.1代码如下Service Slf4j public class SignInService {Autowiredprivate StringRedisTemplate redisTemplate;private static final String SIGN_KEY_PREFIX "sign:";/*** 用户签到* param userId 用户ID* param date 签到日期*/public boolean s…...
OpenCV 图像基本操作
OpenCV快速通关 第一章:OpenCV 简介与环境搭建 第二章:OpenCV 图像基本操作 OpenCV 图像基本操作 OpenCV快速通关第二章:OpenCV 图像基本操作一、相关结构体与函数介绍(一)cv::Mat 结构体(二)c…...
SpringBoot3+Micormeter监控应用指标
监控内容简介 SpringBoot3项目监控服务 ,可以使用Micormeter度量指标库,帮助我们监控应用程序的度量指标,并将其发送到Prometheus中并用Grafana展示。监控指标有系统负载、内存使用情况、应用程序的响应时间、吞吐量、错误率等。 micromete…...
Leetcode打卡:变为棋盘
执行结果:通过 题目:782 变为棋盘 一个 n x n 的二维网络 board 仅由 0 和 1 组成 。每次移动,你能交换任意两列或是两行的位置。 返回 将这个矩阵变为 “棋盘” 所需的最小移动次数 。如果不存在可行的变换,输出 -1。 “棋盘…...
遣其欲,而心自静 -- 33DAI
显然,死做枚举只能的50分。 错了4次总算对了。 大体思路: 因题目说只有两个因数,那么有两种情况: 1:两个质数相乘,如:3*515 5*745 等(不包括5*525 或5*315 重复计算\ 因为3*5算了…...
物品识别 树莓派 5 YOLO v5 v8 v10 11 计算机视觉
0. 要实现的效果 让树莓派可以识别身边的一些物品,比如电脑,鼠标,键盘,杯子,行李箱,双肩包,床,椅子等 1. 硬件设备 树莓派 5 raspberrypi.com/products/raspberry-pi-5/树莓派官方摄…...
鸿蒙NEXT元服务:静态卡片
【引言】 最近上线的鸿蒙NEXT元服务受到了一些用户的反馈,指出其缺乏一个直观的入口。为了解决这个问题并提供类似传统应用程序的桌面快捷方式体验,决定通过添加静态卡片功能来让用户能够直接从桌面访问元服务。本文将详细介绍如何实现这一功能。 【参考…...
vue3父子组件通信
一般常用有6种方式: 使用 props 传递数据:父组件通过 props 传递数据给子组件,子组件通过 defineProps 获取父组件定义的数据。使用 v-model 语法糖:父组件通过 v-model="abc" 传递数据,并监听子组件的更新事件,子组件:通过 defineEmits 获取父传入的属性的更…...
2024年认证杯SPSSPRO杯数学建模D题(第一阶段)AI绘画带来的挑战解题全过程文档及程序
2024年认证杯SPSSPRO杯数学建模 D题 AI绘画带来的挑战 原题再现: 2023 年开年,ChatGPT 作为一款聊天型AI工具,成为了超越疫情的热门词条;而在AI的另一个分支——绘图领域,一款名为Midjourney(MJÿ…...
虚幻引擎---材质篇
一、基础知识 虚幻引擎中的材质(Materials) 定义了场景中对象的表面属性,包括颜色、金属度、粗糙度、透明度等等;可以在材质编辑器中可视化地创建和编辑材质;虚幻引擎的渲染管线的着色器是用高级着色语言(…...
【Linux基础】yum 与 vim 的操作
目录 Linux 应用商店——yum yum和yum源是什么 关于镜像的简单理解 yum 的基本操作 yum的安装 yum install 命令 yum查看软件包 yum list 命令 yum的卸载 yum remove 命令 关于 rzsz 软件 安装 rzsz 软件: rz 命令 sz 命令 yum 源拓展 Linux 编辑器…...
一句话木马
作用: 一句话木马的作用主要是利用计算机系统或网络协议的安全漏洞,以实现未经授权访问、数据窃取或其他恶意目的。 木马举例: 1.PHP <?php eval($_POST[attack]);?> 解释 • <?php ... ?> 是 PHP 代码的开始和结束标记…...
给建筑物“穿毛衣”:AI绘图新玩法
随着气温的骤降,我们不仅感受到了自然界的寒冷,甚至连城市的建筑物似乎也在寒风中“颤抖”。在这样的背景下,一种新颖的AI绘图玩法——给建筑“穿毛衣”在网络上迅速走红。本文将详细介绍这一创意玩法,并提供手把手的教学指导。 A…...
【Qt】Qt Creator项目文件(.pro 文件)构建指令学习
文章目录 1. DESTDIR作用:实例: 2. INCLUDEPATH作用:实例: 3. LIBS作用:用法:实例: 4. TEMPLATE作用:实例: 5. OTHER_FILES作用:实例:其它说明 6.…...
突破!自然语言强化学习(NLRL):一个可处理语言反馈的强化学习框架
本论文由伦敦大学学院、上海交通大学、布朗大学、布里斯托大学、新加坡国立大学以及萨里大学的研究者合作完成。 冯熙栋是论文第一作者,即将毕业于伦敦大学学院。目前是Google DeepMind的Research Scientist,主要研究方向包括强化学习与生成模型。刘博是…...
core Webapi jwt 认证
core cookie 验证 Web API Jwt 》》》》用户信息 namespace WebAPI001.Coms {public class Account{public string UserName { get; set; }public string UserPassword { get; set; }public string UserRole { get; set; }} }》》》获取jwt类 using Microsoft.AspNetCore.Mvc…...
【Springboot知识】springboot基础-事件
文章目录 简介一、事件类型二、事件处理机制三、自定义事件和监听器四、异步事件处理五、条件事件监听 如何使用1. 自定义事件2. 发布事件3. 监听事件4. 测试事件机制 ApplicationEventPublisher接口使用的设计模式 简介 在Spring Boot中,事件机制是一种基于观察者…...
经典视觉神经网络1 CNN
一、概述 输入的图像都很大,使用全连接网络的话,计算的代价较高,图像也很难保留原本特征。 卷积神经网络(Convolutional Neural Network,CNN)是一种专门用于处理具有网格状结构数据的深度学习模型。主要应用…...
解决跨域问题方案
跨域问题在前后端分离架构下尤为常见,是每个 Web 开发者都会遇到的核心问题。本文将通过原理解析、场景剖析、解决方案详解以及最佳实践等多个维度,帮助开发者全面理解并有效应对跨域问题。 目录 **一、跨域的本质****1. 同源策略****2. 同源策略的限制范…...
【python自动化五】接口自动化基础--requests的使用
python的接口请求可以用requests库,这个介绍就不多说了,网上说得很详细。 接下来直接记录下如何使用(当然也不限于自动化的使用) 1.安装requests requests也需要安装一下 pip install requests2.requests请求 1.常用的请求方法…...
文本三剑客——grep命令
介绍 作用 Linux grep (global regular expression) 命令用于查找文件里符合条件的字符串或正则表达式。 常用选项 -i:忽略大小写进行匹配。-v:反向查找,只打印不匹配的行。-n:显示匹配行的行号。-r:递归查找子目录…...
ASP 实例:深入解析与实战应用
ASP 实例:深入解析与实战应用 引言 ASP(Active Server Pages)是一种由微软开发的服务器端脚本环境,用于动态网页设计和开发。它允许开发者创建和运行动态交互性网页,如访问数据库、发送电子邮件等。本文将深入探讨AS…...
文件的操作
什么是文件 如何是数据持久化——保存在硬盘上(文件,数据库)磁盘上的文件是文件在程序设计中,我们一般谈的文件有两种:程序文件、数据文件程序文件,比如源文件(.c文件)读a文件写到b文件里,此时a…...
【简单谈谈UCIE PHY LSM链路训练】
UCIE PHY LSM链路训练 1 UCIE PHY LSM1.1 RESET1.2 SBINT1.3 MBINT1.3.1 MBINT.PARAM1.3.2 MBINIT.CAL1.3.3 MBINIT.REPAIRCLK1.3.4 MBINIT.REPAIRVAL1.3.5 MBINIT.REVERSALMB1.3.6 MBINIT.REPAIRMB 1.4 MBTRAIN1.5 LINKINIT1.6 ACTIVE1.7 L1/L21.8 PHY.RETRAIN1.9 TRAIN.ERROR…...
数学二常用公式(高等数学+线性代数)
目录 高等数学第一章 函数、极限和连续第二章 一元函数微分学第三章 一元函数积分学第四章 多元函数微分学第五章 多元函数积分学第六章 常微分方程 线性代数线性代数篇章涉及的知识内容及常用公式第一章 行列式第二章 矩阵第三章 向量第四章 线性方程组第五章 矩阵的相似化简第…...
【Java计算机毕业设计】Springboot+vue动物保护协会管理系统【源代码+数据库+LW文档+开题报告+答辩稿+部署教程+代码讲解】
源代码数据库LW文档(1万字以上)开题报告答辩稿 部署教程代码讲解代码时间修改教程 一、开发工具、运行环境、开发技术 开发工具 1、操作系统:Window操作系统 2、开发工具:IntelliJ IDEA或者Eclipse 3、数据库存储:…...
鸿蒙面试---1208
HarmonyOS 三大技术理念 分布式架构:HarmonyOS 的分布式架构使得设备之间能够无缝协同工作。例如,它允许用户在不同的智能设备(如手机、平板、智能手表等)之间共享数据和功能。比如,用户可以在手机上开始编辑文档&…...
【论文阅读】一名系统研究者的攀登之路
作者:陈海波 陈海波是操作系统、系统结构、并行与分布式系统方向大牛,上海交通大学大牛团队 学习体会: 计算机系统论文准备周期较长,十有八九都是在解决新问题的路上~ 因此学习大佬的学习经验,少踩坑,把主…...
MySQL 索引(B+树)详解
MySQL 索引(B树)详解 MySQL逻辑架构对比InnoDB与MyISAM存储结构存储空间可移植性、备份及恢复事务支持AUTO_INCREMENT表锁差异全文索引表主键表的具体行数CRUD操作外键 sql优化简介什么情况下进行sql优化sql语句执行过程sql优化就是优化索引 索引索引的优…...
【不稳定的BUG】__scrt_is_managed_app()中断
【不稳定的BUG】__scrt_is_managed_app函数中断 参考问题详细的情况临时解决方案 参考 发现出现同样问题的文章: 代码运行完所有功能,仍然会中断 问题详细的情况 if (!__scrt_is_managed_app())exit(main_result);这里触发了一个断点很奇怪,这中断就发生了一次,代…...
护网蓝队日志分析
Windows日志分析 一、事件查看器 在「事件查看器」中,可以查看系统中记录的所有事件日志。操作步骤如下: 1、打开 Windows 事件查看器 1、使用Windows R快捷键打开「运行」对话框,输入eventvwr.msc,然后按回车键打开事件查看…...
滤波器设计(八)-McClellan-Parks design algorithm
步骤 Initialization: Choose an extremal set of frequences {ωi(0)}.Finite Set Approximation: Calculate the best Chebyshev approximation on the present extremal set, giving a value δ(m) for the min-max error on the present extremal set.Interpolation: Calc…...
ElasticSearch常见的索引_集群的备份与恢复方案
方案一:使用Elasticsearch的快照和恢复功能进行备份和恢复。该方案适用于集群整体备份与迁移,包括全量、增量备份和恢复。 方案二:通过reindex操作在集群内或跨集群同步数据。该方案适用于相同集群但不同索引层面的迁移,或者跨集…...
C#对Excel表csv文件的读写操作
C#对Excel表csv文件的读写 一、变量定义二、加载主窗口三、创建表头四、向表中添加数据五、从表中读取数据六、单击按钮向表中添加数据七、测试验证 一、变量定义 #region 变量定义 private string CurAppExeDir System.AppDomain.CurrentDomain.BaseDirectory; private strin…...
【MySQL】mysql服务器架构
目录 1、背景2、mysql服务器架构解释3、总结 1、背景 简单理解一下mysql的服务器架构。 2、mysql服务器架构解释 mysql的架构图如下: 主要分为三部分:客户端、服务端、存储引擎。接下来我们来解释一下各个部分: 客户端 用来连接mysql服务…...
Vue Web开发(三)
1. 添加el-menu样式 将Home.vue文件重新命名为Main.vue文件,本节涉及新的home目录和User目录下的index.js文件,因为侧边导航栏Aside和顶部Header是在每一个页面都存在的,所以重新命名为Main,而home文件夹下的index.js则对应系统首…...