Lua中的元表(metatable)、元方法(metamethod)详解
在第一次看见这两样东西的时候,可能会觉得它很深奥,但其实很好理解,虽然实际上它可能真的很深奥。(小若:停!滚粗。)
1.知道为什么1 + 1 = 2吗?
为什么在Lua中,1+1会等于2呢?(小若:难道除了Lua,其他地方就不等于2了?)
为什么数字和数字相加是合法的,为什么table和table相加就会报错?大家有想过这些问题吗?
没错,规则,这一切都只是规则而已,Lua规定了数字之间可以进行加减乘除,而table之间则不可以。
这是因为,在人类世界里,并没有table和table相加的概念。
而在Lua中,进行这些规则限定的秘密就在于元表和元方法。
2.元方法
元方法,听起来很深奥,其实它就是格子类型变量之间进行特殊操作的函数。
比如,数字的相加,它可能仅仅是一个函数。
比如:1+1 ,在底层里,它可能是这样的:add(1, 1)。而add函数就是用来计算两个数字间相加的结果。
再如:10X15,它可能是这样的:mul(10, 15)。mul函数就能返回两个数字相乘的结果。
(可能这例子不太恰当,但就是这么个意思~)
最后,如果是两个table呢?
local t1 = {};
local t2 = {};
t1 + t2;
它可能就是这样的:????
没错,Lua中不存在可以计算两个table相加的函数,也就是说,不存在这样的元方法。
3.元表
元表本身并没有什么作用,它是用来存放元方法的一个table。
Lua中的每一个值都有或者可以有一个元表,table和userdata可以各种拥有独立的元表。
但是,其他类型的值就只能共享其类型所属的元表,比如,数字,所有的数字都共用一个元表。
4.改变规则
如果说,我们就是希望将两个table进行相加呢?
试试看,如下代码:
local t1 = {};
local t2 = {};
local result = t1 + t2;
直接运行肯定报错的。
因此,为了满足我们这种需求,Lua允许我们修改元表。
一个元表,其实就是一个table值,所以,我们只需要新建一个table,添加元方法即可。
比如加法运算的元方法就是:__add,这是Lua规定的。
只要某个值的元表里含有__add这个元方法,那就可以使用+号进行运算。
如下代码:
-- 创建一个元表
local mt = {};
mt.__add = function(t1, t2)
print("两个table相加的结果就是...神经病啊!table有什么好相加的啊!");
end
local t1 = {};
local t2 = {};
-- 给两个table设置新的元表
setmetatable(t1, mt);
setmetatable(t2, mt);
-- 进行加法操作
local result = t1 + t2;
首先创建了一个table变量mt,给这个table新增一个元素__add,这个table就拥有了作为元表的资格了。
然后创建两个新的table变量,使用setmetatable函数给table设置新的元表,此时,两个table变量就以mt作为元表了。
最后,对t1和t2进行加法操作,这时就会从元表中查找__add元方法,如果找到的话,就调用这个元方法对两个变量进行加法操作。
输出结果如下:
[LUA-print] 两个table相加的结果就是…神经病啊!table有什么好相加的啊!
就是这么简单,元表和元方法其实就是给Lua里的值设定一些操作,比如加法、减法之类的,让我们可以对这些操作自定义。
不过,有几点要特别注意的:
a.创建一个新的table变量时,它是不存在元表的(可以用getmetatable函数获取某个对象的元表,就能知道这个对象有没有元表存在了)
b.在Lua中,只能设置table的元表,其他类型的值的元表,只能通过C代码来完成
Lua中的元表(metatable)、元方法(metamethod)详解的更多相关文章
- Lua中的元表与元方法学习总结
前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了"+"符号,就可以进行类的加法运算.在Lu ...
- Lua中的元表与元方法
[前言] 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了“+”符号,就可以进行类的加法运算.在Lua中也有这个道理 ...
- Lua中的元表和元方法
Lua中每个值都可具有元表. 元表是普通的Lua表,定义了原始值在某些特定操作下的行为.你可通过在值的原表中设置特定的字段来改变作用于该值的操作的某些行为特征.例如,当数字值作为加法的操作数时,Lua ...
- lua编程之元表与元方法
一. 前言 lua是一种非常轻量的动态类型语言,在1993年由由Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo等人 ...
- Lua中强大的元方法__index详解
今天要来介绍比较好玩的内容:__index元方法 我是备胎,记得回头看看 咳咳,相信每一位女生都拥有或者不知不觉中拥有了一些备胎,啊!当然,又或许是成为过别人的备胎. 没有备胎的人,就不是完整的人生. ...
- Lua中的loadfile、dofile、require详解
1.loadfile——只编译,不运行 loadfile故名思议,它只会加载文件,编译代码,不会运行文件里的代码.比如,我们有一个hellofile.lua文件: 复制代码代码如下: print(“h ...
- lua元表(metatable)和元方法(metamethod)
(一) 元表概念: 引言:Lua中的每个值都有一套预定义的操作集合,如数字相加等.但无法将两个table相加,此时可通过元表修改一个值的行为,使其在面对一个非预定义的操作时执行一个指定操作. 访问机制 ...
- 【游戏开发】小白学Lua——从Lua查找表元素的过程看元表、元方法
引言 在上篇博客中,我们简单地学习了一下Lua的基本语法.其实在Lua中有一个还有一个叫元表的概念,不得不着重地探讨一下.元表在实际地开发中,也是会被极大程度地所使用到.本篇博客,就让我们从Lua查找 ...
- lua metatable和metamethod元表和元方法
Lua中提供的元表是用于帮助Lua数据变量完成某些非预定义功能的个性化行为,如两个table的相加.假设a和b都是table,通过元表可以定义如何计算表达式a+b.当Lua试图将两个table相加时, ...
随机推荐
- OO 第三单元
一.JML语言理论基础 JML 是用于对 Java 程序进行规格化设计的一种表示语言,为严格的程序设计提供了一套行之有效的方法. 我个人对于 JML 的几点看法: JML 的规格化设计相较于自然语言的 ...
- Java后端进阶-网络编程(Netty责任链Pipeline)
设计模式-责任链模式 一个责任链模拟demo package com.study.hc.net.netty.demo; // -----链表形式调用------netty就是类似的这种形式 publi ...
- ElasticSearch-03-远行、停止
在Windows下执行elasticsearch.bat 在Linux下运行./elasticsearch 指定集群名称和节点名称: ./elasticsearch --cluster.name my ...
- 16. Vue2.4+新增属性$attrs
vm.$attrs简介 首先我们来看下vue官方对vm.$attrs的介绍: 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外).当一个组件没有声明 ...
- Java封装接口统一返回数据模板
现在大多数都使用前后端分离开发模式,前端通过Ajax请求访问后台服务器,后台返回JSON数据供前端操作,这里编写一个统一返回数据模板类,方便日后操作 public class R extends Ha ...
- SpringCloud(四)GateWay网关
GateWay网关 概述简介 Gateway是在 Spring生态系统之上构建的AP网关服务,基于 Spring5, Spring Boot2和 Project Reactor等技术. Gateway ...
- 从苏宁电器到卡巴斯基第26篇:难忘的三年硕士时光 IV
录课,录课,还是录课 开题结束以后,已经是三月的下旬,当时我在考虑要不要回家,毕竟学校这里也没什么事了,我待在学校还得付出一定的花销.后来我考虑到在家的话,只有晚上才能够录课,而在学校的话,整个白天都 ...
- 使用SSH端口做端口转发以及反向隧道
目录 SSH做本地端口转发 SSH做反向隧道(远程端口转发) 用autossh建立稳定隧道 SSH开启端口转发需要修改 /etc/ssh/sshd_config配置文件,将 GatewayPorts修 ...
- Windows核心编程 第六章 线程基础知识 (上)
第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ...
- nodejs-Buffer(缓冲区)
Node.js Buffer(缓冲区) JavaScript 语言自身只有字符串数据类型,没有二进制数据类型. 但在处理像TCP流或文件流时,必须使用到二进制数据.因此在 Node.js中,定义了一个 ...