在lua中,每个值都有其对应的操作,比如数值型有加减乘除等操作,字符串型有连接截取等操作,那么这些操作(加减乘除,连接截取等)定义在什么地方呢?定义在这些值默认的元表中,如果想修改这些操作(比如加法)就得修改其默认的元表,这样一来整型值所有的加法操作都被修改了。

table和userdata型没有默认元表,所以我们可以很容易修改其操作行为,比如对于table类型,我们是没有加法操作的,即两个table是不能够相加的,如果这时候想实现其相加操作怎么办呢,此时就可以为这两个table每一个设置一个元表,在其对应的元表中设置__add()函数, "__add" 是元表的键名(元表的键名也称之为事件(event),一般以 2 个下划线 "_" 开头), "__add" 函数是这个相加操作的元方法(metamethod)。对于值的操作,Lua 都将其关联上一个被称作事件的指定健,当 Lua 需要对一个值发起这些操作中的一个时, 它会去检查值的元表里是否有对应事件。如果有,则键名对应的值(元方法)将控制 Lua 怎样去执行这个操作,有人可能会有疑问,为什么相加操作用__add(),而不是其他,在此的解释是键名是固定写法,在lua中我们可以重定义的元方法有这些:

t1 = {"a""b""c""d"}
t2 = {56789}
mt = {}
mt.__add = function(a, b)
    local tbl = {}
    local ret = {}
    for k, v in pairs(a) do tbl[v] = true end
    for k, v in pairs(b) do tbl[v] = true end
    for k, v in pairs(tbl) do
        table.insert(ret, k)
    end
    return ret
end
setmetatable(t1, mt)
setmetatable(t2, mt)
t = t1 + t2
for k, v in pairs(t) do print(v) end

在执行加法操作时(t = t1 + t2),首先检查该+运算符的两个table操作数的元表中是否有相加操作的元方法,如果没有则会报错,否则执行。

上述是对执行加法操作的元方法的举例,其他的操作类似。除此之外还有几个非常重要的元方法需要注意:__index,__newindex等。

__index用来对表进行访问:
当你通过键值对表进行访问的时候,如果该键没有值,则会查找对应的元表中是否存在该键对应的值,如果不存在则返回nil,否则返回__index对应的值。

Lua查找一个表元素时的规则,遵循如下3个步骤:

  • 1.在表中查找,如果找到,返回该元素,找不到则继续
  • 2.判断该表是否有元表,如果没有元表,返回nil,有元表则继续。
  • 3.判断元表有没有__index方法,如果__index方法为nil,则返回nil;如果__index方法是一个表,则重复1、2、3;如果__index方法是一个函数,则返回该函数的返回值。
__newindex用于对表进行更新。

在对一个表中不存在的索引赋值时,不会直接把该值加到该表中,而是会把该值加入到该表的元表中。

mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })print(mytable.key1)mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)

以上输出结果为

value1
nil 新值2
新值1 nil

以上实例中表设置了元方法 __newindex,在对新索引键(newkey)赋值时(mytable.newkey = "新值2"),会调用元方法,而不进行赋值。而如果对已存在的索引键(key1),则会进行赋值,而不调用元方法 __newindex。

以上只是对lua元表元方法的简单总结,如果想详细了解其用法的可以参考以下这两篇文章,个人认为写的比较好,并且本文一部分内容是借鉴以下两位的:

http://www.runoob.com/lua/lua-metatables.html

http://dhq.me/lua-learning-notes-metatable-metamethod

lua 元表/元方法相关推荐

  1. lua元表的相关知识

    setmetatable()和getmetatable(): local a=8 local b = "s" local t = {1,2}--在Lua代码中,只能设置table的 ...

  2. lua学习笔记之元表和元方法

    元表允许当遇到未知操作时,改变值的行为.例如,使用元表,可以定义表a与表b的关系运算a+b.当lua尝试两个表相加时,会检查是否其中一个有元表并且元表是否有__add字段. 元表在面向对象的术语中是一 ...

  3. lua元表和元方法 《lua程序设计》 13章 读书笔记

    lua中每个值都有一个元表,talble和userdata可以有各自独立的元表,而其它类型的值则共享其类型所属的单一元表.lua在创建table时不会创建元表. t = {} print(getmet ...

  4. lua的元表metatable及元方法

    前言 元表对应的英文是metatable,元方法是metamethod.我们都知道,在C++中,两个类是无法直接相加的,但是,如果你重载了"+"符号,就可以进行类的加法运算.在Lu ...

  5. Lua程序设计 | 模块和包、泛型迭代器和for、元表和元方法

    From<Programming in Lua> by Roberto Ierusalimschy 文章目录 模块和包 函数 require 模块重命名 搜索路径 搜索器 Lua语言中编写 ...

  6. Lua语言编程学习之路02----第13章 元表与元方法

    前言   在Lua中我们无法直接对两个table进行相加,无法对函数进行比较,也无法调用一个函数. 于是Lua可以通过修改一个值的行为,使其在面对一个非预定义的操作时执行一个自己实现的操作.比如两个t ...

  7. Lua 元表及常见元方法

    一.什么是元表 Lua 中的 table 使用起来有点像c++中的 map 或者 unordered_map ,都是通过对应的key 获取对应的value.如果访问了表中不存在的key时,就会触发Lu ...

  8. Lua 学习元表,元方法

    前言 Lua本身没有面向对象的思想,但是可以根据表.元表.元方法来靠近它 一.元表与元方法的概念 Lua中每个值都可具有元表.元表是普通的Lua表,定义了原始值在某些特定操作下 的行为.例如,当tab ...

  9. Lua中强大的元方法__index详解

    今天要来介绍比较好玩的内容--__index元方法 1.我是备胎,记得回头看看 咳咳,相信每一位女生都拥有或者不知不觉中拥有了一些备胎,啊,当然,又或许是成为过别人的备胎. 没有备胎的人,就不是完整的 ...

最新文章

  1. 非常好!!!---bash转义序列笔记---打印语句printf用法【转】
  2. InfluxDB命令使用
  3. Oracle中NVARCHAR2与VARCHAR2的区别
  4. Nginx中worker connections问题的解决方法
  5. ITK:计算图像谱密度
  6. 《Android编程权威指南》PhotoGallery应用梳理
  7. JupyterHub on Kubernetes-Helm安装
  8. hibernate 查询id为空懒加载_hibernate 查询时指定查询字段、级联表的一种方式
  9. fiddler限速/弱网模拟
  10. python之使用request模块发送post和get请求
  11. kubernetes(k8s):使用statefulset部署mysql主从集群
  12. SpringBoot + React汽车租赁管理系统 附带详细运行指导视频
  13. Win10 C盘修改用户文件夹
  14. 论文阅读一《Region Proposal by Guided Anchoring》
  15. [转载] 晓说——第1期:揭秘游戏规则奥斯卡走下“神坛“
  16. 2.4 线性丢番图方程
  17. 2022年Github学生包白嫖!
  18. java中的notify和notifyAll有什么区别?
  19. 网站关键词该如何优化?
  20. brooks levitate_超越Boost的脚感: Brooks Levitate2体验

热门文章

  1. 机器学习教会我们的六件事
  2. linux twiki 添加权限,Linux安装TWiki
  3. TOMCAT websocket 多连接内存泄漏与jetty对比分析
  4. 高仿真的类-ApplicationContextAware
  5. 注解能力ApplicationContext作为 IoC 容器示例
  6. 收货地址 - 需求分析与表设计
  7. Spring模块化设计:Spring功能特性如何在不同模块中组织?
  8. 数据库设计对性能的影响
  9. ActiveMQ 消息持久化
  10. 计算机考试时间改革,武汉计算机二级考试时间和改革变化2021